3 回答

TA贡献2037条经验 获得超6个赞
您的方法不是线程安全的。it.hasNext()
在每次迭代时调用,因此您可以相信获得了预期结果,但Iterator
不是线程安全的。因此,如果同时执行多个Callable
s,则使用迭代器会产生不可预测的结果。
使用 Thread 或 Callable 当然可以利用并行性,但在使用迭代器时需要添加显式同步。
虽然使用Callable
显式同步在某种程度上很烦人。
作为替代方案,您可以使用确保线程安全的集合,例如CopyOnWriteArrayList
. 例如,将原始列表包装在CopyOnWriteArrayList
复制构造函数中,例如:
List<Foo> copyList = new CopyOnWriteArrayList<>(list);
或者,您也可以更简单地使用并行流,这将使您的代码变得不那么冗长,但它在幕后的线程池的可配置性较低(在某些情况下,这很重要):
list.parallelStream().forEachOrdered(this::method1);

TA贡献1943条经验 获得超7个赞
首先尝试获取迭代值。
final <class> nextItem = it.next();
Future<?> future = service.submit(() -> { method1(nextItem); });
futures.add(future);

TA贡献1936条经验 获得超7个赞
我哪里做错了?
你有一个线程正在执行此操作:
while ( it.hasNext() ) { Future<?> future = service.submit(...task...); futures.add(future); }
该线程不断调用it.hasNext()
,但它从不调用it.next()
。
您还有其他线程(线程池的工作线程)在调用,it.next()
但这些线程独立于循环运行。如果循环向执行器服务提交任务并将 future 添加到列表所需的时间小于工作线程选择并执行任务所需的时间,则循环将领先于执行器服务,它会提交比您预期更多的任务。
添加回答
举报