【发布时间】:2018-01-05 01:56:01
【问题描述】:
我有一个类似下面的 API,其中 Baz 是工作人员实现。
这个Bar 需要是线程安全的,这在与 Baz 的回调交互时会变得很棘手。
需要在回调中引用当前的 baz 实例(可以在工作线程上调用或同步调用)。 cmets 应该显示问题:
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();
}
}
【问题讨论】:
标签: java multithreading asynchronous thread-safety synchronous