Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Collections.synchronizedlist()在从末尾迭代时删除元素_Java_Multithreading_Collections - Fatal编程技术网

Java Collections.synchronizedlist()在从末尾迭代时删除元素

Java Collections.synchronizedlist()在从末尾迭代时删除元素,java,multithreading,collections,Java,Multithreading,Collections,我正在使用Collections.Synchronizedlist()使我的arraylist线程安全。我想问的是以下代码是线程安全的,即从末尾迭代列表时删除:- pendingExecutionList = Collections.synchronizedList(new ArrayList<>(initialCapacity)); 当多个线程添加到此列表时,上述代码仅由单个线程执行 我希望避免在synchronized(list)上使用迭代器,因为这不是故障保护。相反,您实际上

我正在使用
Collections.Synchronizedlist()
使我的
arraylist
线程安全。我想问的是以下代码是线程安全的,即从末尾迭代列表时删除:-

pendingExecutionList = Collections.synchronizedList(new ArrayList<>(initialCapacity));
当多个线程添加到此列表时,上述代码仅由单个线程执行


我希望避免在
synchronized(list)
上使用迭代器,因为这不是故障保护。

相反,您实际上是在每个元素上获得一次锁。这有一个风险,比您在进行检查时仅持有锁要慢


我建议你考虑使用一个适当的排序。这将对队列进行排序,以便您下一步要处理的队列将处于开始位置,并且无论等待任务的数量如何,删除的成本相对较低。

如果我正确理解了您的工作流管道,我建议尝试某种
阻塞队列的变体,而不是
同步列表()

ArrayBlockingQueue
将允许您公平地安排执行,并应保持多个生产者的缓存相当热(除非生产者开始超越缓存预取器,在这种情况下,您将遇到错误共享)


如果您想尝试,可以查看JDK之外的MPSC(多生产商、单消费者)队列,如Nitsan Wakart或。

答案是否定的,它不是线程安全的。非常清楚:当用户在返回的列表上进行迭代时,必须手动同步该列表。为什么?你能explain@ingrid,我的问题有点不同,因为我的用例不同。我不会把锁带到任何地方。你能解释一下吗?@maveroid如果你在
集合上使用方法。synchronizedList
其中所有方法都是
同步的
无论你想不想承认它,你都在使用锁;)好的,知道了,但是锁在add()和remove()上,而不是在迭代中。对吗?@maveroid是的,并且
get()
所以这是在每次迭代中至少获取并释放一次锁。@maveroid我不是说这是不可取的,但这取决于您的条件和过程需要多长时间。i、 您可能希望能够在任务运行时添加任务。但列表的大小不是固定的。它可以生长。您更喜欢BlockingQueue的哪种变体?如果您不是为移动或嵌入式环境开发,那么您很可能能够在应用程序启动时分配适当的缓冲区。像Martin Thompson(机械同情的家伙/一个捣乱分子)说,无界队列经常被用作一个能使系统失去记忆的创可贴(参见)。不过,如果您觉得使用无界队列更好,可以尝试使用
LinkedBlockingQueue
或非阻塞
ConcurrentLinkedQueue
for (int i = pendingExecutionList.size() - 1; i >= 0; i--) 
{
   if (someCondition(pendingExecutionList.get(i))) 
   {
      process(pendingExecutionList.remove(i));
   }
}