gpt4 book ai didi

java - 交叉同步块(synchronized block)

转载 作者:行者123 更新时间:2023-11-30 11:28:00 27 4
gpt4 key购买 nike

我有一个函数,它从 ThreadB 发送通知到线程 ThreadA 并等待从 ThreadA 返回到 ThreadB 的通知.

AB 通知然后 BA 通知 ThreadA 读取 ThreadB 数据,并在完成时向 ThreadB 发送通知。

sendNotifyAndWaitNotify 在 ThreadB 中运行。

在同一个对象上一个一个地同步可能看起来很奇怪,但是 B.sync.notify(); 只会在它退出同步块(synchronized block)时发送通知,如果我将所有内容都写在一个 block 中我会先等待,只有在退出同步块(synchronized block)时才会发出通知。这是 Not Acceptable 。

void sendNotifyAndWaitNotify() {
synchronized(B.sync) {
B.sync.notify();
}
//ThreadA reads ThreadB data
synchronized (B.sync) {
try {
debug("start waiting for notify");
B.sync.wait();
} catch (Exception e) {
error( e.toString());
}
}
debug("reader sleep done");
}

但是这个函数是不正确的,因为ThreadA可以在ThreadB没有启动等待的时刻读取数据通知ThreadB。是否可以通过像下面这样跨越同步块(synchronized block)来解决问题:

void sendNotifyAndWaitNotify() 
{
synchronized(B.sync) // block #1
{
synchronized(B.sync) // block #2
{
B.sync.notify();
}

//ThreadA reads ThreadB data

try
{
debug("start waiting for notify");
B.sync.wait();
} catch (Exception e) {
error( e.toString());
}
debug("reader sleep done");
}
}

我预计 ThreadA 将在退出同步块(synchronized block) #1 而不是 #2 后被唤醒。我希望 block #2 中的代码也许第二个 block 最好在不同的同步对象上制作?

我必须使用 java 1.4。

最佳答案

您应该始终使用循环条件保护对 wait() 的调用。

synchronized(B.sync){
while(!myConditionIsSatisfied){
B.sync.wait();
}
/* Do critical stuff */
}

这样,如果在线程到达同步块(synchronized block)时您的条件已经满足,它就不会等待任何事情。

用循环条件保护等待的另一个原因是 wait() 被其合约允许虚假地唤醒。如果发生这种情况,如果您的条件不满足,您希望将线程发送回 wait()

另请参阅:JavaDoc for Object.wait(long) Object.wait() 是对 Object.wait(0) 的调用

摘录(强调我的):

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one:

 synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}

关于java - 交叉同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19051952/

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