3
我有一個如下所示的API,其中Baz
是工作者的實施。 這個Bar
需要是線程安全的,當與Baz的回調交互時,這會變得棘手。維護線程安全,同時防止死鎖可能同步回調
當前baz實例需要在回調中引用(可以在工作線程或同步調用)。 的意見應該顯示問題:
final class Bar {
final Lock lock = new ReentrantLock();
Baz baz; // Guarded by lock.
void run() { // Called by any thread.
lock.lock();
if (baz.isRunning()) {
lock.unlock();
return;
}
baz = new Baz();
// If it unlocks here, the next line may execute on the wrong Baz.
// If it doesn't unlock here, there will be a deadlock when done() is called synchronously.
// lock.unlock();
baz.run(new Baz.Callback() { // May be called synchronously or by Baz worker thread.
@Override
public void done() {
lock.lock();
baz = new Baz();
lock.unlock();
}
});
}
}
有沒有正確地做這項工作,同時也不會導致死鎖的好方法?
編輯:更簡潔:
final class Foo {
final Lock lock = new ReentrantLock();
void run() {
lock.lock();
worker.enqueue(new Callback() {
@Override void complete() {
lock.lock(); // Could cause deadlock.
}
});
lock.unlock();
}
}
巴茲指派需要在回調,但。 –
編輯澄清。 –
爲什麼它應該在回調中被引用?我發佈的代碼確保baz不會重新啓動直到回調完成 –