多线程库暴露不安全的ArrayList

Bas*_*ixp 5 java multithreading

我在Java中使用一个返回ArrayList的共享库; 当我迭代它时,可能会抛出ConcurrentModificationException,我正在寻找100%(?)保证是安全的.我正在考虑下面的事情,我很欣赏任何意见.

data_list是从MT库返回的ArrayList <>.

boolean pass = true;

ArrayList<Something> local = new ArrayList<Something>(256);

for (int spin=0; spin<10; ++spin)
{
  try {
    local.addAll(data_list);
  }
  catch (java.util.ConcurrentModificationException ce) {
    pass = false;
  }
  finally {
    if (pass) break;
    pass = true;
  }
}
Run Code Online (Sandbox Code Playgroud)

假设变量passtrue,我应该如何操作本地?

Ste*_*ker 9

没有安全的方法来做到这一点. 你不应该抓住ConcurrentModificationException.

此类的iterator和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对列表进行结构修改,除了通过迭代器自己的remove或add方法之外,迭代器将抛出ConcurrentModificationException.因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.

请注意,迭代器的故障快速行为无法得到保证,因为一般来说,在存在不同步的并发修改时,不可能做出任何硬性保证.失败快速迭代器会尽最大努力抛出ConcurrentModificationException.因此,编写依赖于此异常的程序以确保其正确性是错误的:迭代器的快速失败行为应该仅用于检测错误.

一些集合,比如HashMap,甚至可以在使用这种方式时进入无限循环.这是对它如何发生的解释.

不应该这样做.没有正确的方法来做到这一点.

要么你误解了图书馆的运作方式,要么你需要用一个有能力的开发人员编写的库来切换你的库.

你在用什么图书馆?


rap*_*h97 -2

我没有任何根本性的改变,但我认为代码可以简化一点:

ArrayList<Something> local = new ArrayList<Something>(256);

for (int spin=0; spin<10; ++spin)
{
  try {
    local.addAll(data_list);
    break;
  }
  catch (java.util.ConcurrentModificationException ce) {}
}
Run Code Online (Sandbox Code Playgroud)