3 回答

TA貢獻(xiàn)2037條經(jīng)驗 獲得超6個贊
您的方法不是線程安全的。it.hasNext()
在每次迭代時調(diào)用,因此您可以相信獲得了預(yù)期結(jié)果,但Iterator
不是線程安全的。因此,如果同時執(zhí)行多個Callable
s,則使用迭代器會產(chǎn)生不可預(yù)測的結(jié)果。
使用 Thread 或 Callable 當(dāng)然可以利用并行性,但在使用迭代器時需要添加顯式同步。
雖然使用Callable
顯式同步在某種程度上很煩人。
作為替代方案,您可以使用確保線程安全的集合,例如CopyOnWriteArrayList
. 例如,將原始列表包裝在CopyOnWriteArrayList
復(fù)制構(gòu)造函數(shù)中,例如:
List<Foo> copyList = new CopyOnWriteArrayList<>(list);
或者,您也可以更簡單地使用并行流,這將使您的代碼變得不那么冗長,但它在幕后的線程池的可配置性較低(在某些情況下,這很重要):
list.parallelStream().forEachOrdered(this::method1);

TA貢獻(xiàn)1943條經(jīng)驗 獲得超7個贊
首先嘗試獲取迭代值。
final <class> nextItem = it.next();
Future<?> future = service.submit(() -> { method1(nextItem); });
futures.add(future);

TA貢獻(xiàn)1936條經(jīng)驗 獲得超7個贊
我哪里做錯了?
你有一個線程正在執(zhí)行此操作:
while ( it.hasNext() ) { Future<?> future = service.submit(...task...); futures.add(future); }
該線程不斷調(diào)用it.hasNext()
,但它從不調(diào)用it.next()
。
您還有其他線程(線程池的工作線程)在調(diào)用,it.next()
但這些線程獨立于循環(huán)運行。如果循環(huán)向執(zhí)行器服務(wù)提交任務(wù)并將 future 添加到列表所需的時間小于工作線程選擇并執(zhí)行任務(wù)所需的時間,則循環(huán)將領(lǐng)先于執(zhí)行器服務(wù),它會提交比您預(yù)期更多的任務(wù)。
添加回答
舉報