我試圖用CyclicBarrier
重新實現我的併發代碼,這對我來說是新的。我可以沒有,但我的時間試用這對我的其他的解決方案,這個問題我已經是用下面的代碼死鎖情況:爲什麼`ExecutorService`不能一致地調度線程?
//instance variables (fully initialised elsewhere).
private final ExecutorService exec = Executors.newFixedThreadPool(4);
private ArrayList<IListener> listeners = new ArrayList<IListener>();
private int[] playerIds;
private class WorldUpdater {
final CyclicBarrier barrier1;
final CyclicBarrier barrier2;
volatile boolean anyChange;
List<Callable<Void>> calls = new ArrayList<Callable<Void>>();
class SyncedCallable implements Callable<Void> {
final IListener listener;
private SyncedCallable(IListener listener) {
this.listener = listener;
}
@Override
public Void call() throws Exception {
listener.startUpdate();
if (barrier1.await() == 0) {
anyChange = processCommons();
}
barrier2.await();
listener.endUpdate(anyChange);
return null;
}
}
public WorldUpdater(ArrayList<IListener> listeners, int[] playerIds) {
barrier2 = new CyclicBarrier(listeners.size());
barrier1 = new CyclicBarrier(listeners.size());
for (int i : playerIds)
calls.add(new SyncedCallable(listeners.get(i)));
}
void start(){
try {
exec.invokeAll(calls);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void someMethodCalledEveryFrame() {
//Calls some Fisher-something method that shuffles int[]
shufflePIDs();
WorldUpdater updater = new WorldUpdater(listeners, playerIds);
updater.start();
}
我使用調試器Android Studio中(的IntelliJ)在這個暫停執行階段。我得到的多線程顯示我的await
電話爲我最後的代碼被執行
- >
Unsafe.park
- >
LockSupport.park
- >
AbstractQueuedSynchronizer$ConditionObject.await
- >
CyclicBarrier.doWait
- >
CyclicBarrier.await
至少一個線程將是有這樣的堆棧:
- >Unsafe.park
。
- >LockSupport.park
- >AbstractQueuedSynchronizer$ConditionObject.await
- >LinkedBlockingQueue.take
- >ThreadPoolExecutor.getTask
- >ThreadPoolExecutor.runWorker
- >ThreadPoolExecutor$Worker.run
- >Thread.run
我注意到CyclicBarrier
在這些後面的雜散線程中不起作用。
processCommons
是調用exec.invokeAll
(在3個聽衆),我想這意味着我跑出來的線程。但很多時候這不會發生,所以請有人澄清爲什麼ExecutorService
不能一致地安排我的線程?他們有自己的堆棧和程序計數器,所以我會認爲這不成問題。我只有一次運行max 4。有人幫助我瞭解數學嗎?
我最初批准這個是因爲你強調「_exactly_ four」,「不多,不少」,這看起來很深刻。我現在意識到這只是錯誤的:_like_我嘗試使用'CyclicBarrier'。它只是不適合這裏,所以感謝那個指針。 – John