【发布时间】:2016-07-10 23:03:37
【问题描述】:
我正在尝试使用CyclicBarrier 重新实现我的并发代码,这对我来说是新的。我可以不用它,但我正在对我的其他解决方案进行试验,我遇到的问题是使用以下代码出现死锁情况:
//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 is 调用exec.invokeAll(在 3 个侦听器上),我想这意味着我的线程用完了。但是很多时候这不会发生,所以请有人澄清为什么ExecutorService 不能始终如一地安排我的线程?他们有自己的堆栈和程序计数器,所以我认为这不是问题。我一次最多只能运行 4 个。有人帮我算算吗?
【问题讨论】:
标签: java multithreading synchronization cyclicbarrier