gpt4 book ai didi

java - 维护线程安全,同时防止可能发生同步回调的死锁

转载 作者:行者123 更新时间:2023-12-03 17:40:01 26 4
gpt4 key购买 nike

我有一个如下所示的 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();
}
}

最佳答案

不确定是否完全实现了您想要实现的目标,但也许这就是您正在寻找的东西?

final class Bar {
final Lock lock = new ReentrantLock();
Baz baz = new Baz();

void run() {
if (!lock.tryLock()) {
return;
}
try {
CountdownLatch callbackFlag = new CountdownLatch(1);
baz.run(new Baz.Callback() {
@Override
public void done() {
callbackFlag.countDown();
}
});
try {
callbackFlag.await(); // better use overloaded method with max timeout waiting. you don't probably want to wait forever
baz = new Baz(); // do you really want to reinit Baz on each execution?
} catch (InterruptedException e) {
// decide what you want to happen here
}
} finally {
lock.unlock();
}
}
}

关于java - 维护线程安全,同时防止可能发生同步回调的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45382932/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com