Collections.synchronizedlist()从结束迭代时删除元素

时间:2016-04-18 08:01:39

标签: java multithreading collections

我使用var myApp = angular.module('myapp'); myApp.controller('MapDisplayCtrl', function($http, $scope) { //listen to the 'SendMapData' event and get the co-ordinates //draw a google map using the co-ordinates }); 使我的Collections.Synchronizedlist()线程安全。我想问的是以下代码线程安全,即从末尾迭代列表时删除: -

arraylist

我在主线程中创建列表。并从不同的线程添加到此列表。但是,迭代和删除只能从一个Scheduled线程完成,如下所示: -

pendingExecutionList = Collections.synchronizedList(new ArrayList<>(initialCapacity));

当多个线程添加到此列表时,上述代码仅由单个线程执行。

我想避免在for (int i = pendingExecutionList.size() - 1; i >= 0; i--) { if (someCondition(pendingExecutionList.get(i))) { process(pendingExecutionList.remove(i)); } } 上使用迭代器,因为这不是故障安全的。

2 个答案:

答案 0 :(得分:3)

而是持有锁,实际上每个元素获得一次锁定。在您进行检查时,这可能比仅仅握住锁更慢。

我建议您考虑使用具有适当排序的PriorityQueue。这将对队列进行排序,以便您接下来要处理的队列将在开始时,无论等待任务的数量如何,删除的成本都相对便宜。

答案 1 :(得分:1)

如果我正确理解您的工作流程管道,我建议您尝试使用BlockingQueue的一些变体而不是synchronizedList()

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

如果您有进行实验的心情,可以查看JDK之外可用的MPSC(多个生产者,单个消费者)队列,如Nitsan Wakart的MpscArrayQueue或{{ 3}}