gpt4 book ai didi

java - 以下从某些队列实现中检索整数值的代码是否正确

转载 作者:行者123 更新时间:2023-12-02 05:03:28 25 4
gpt4 key购买 nike

我正在从互联网上阅读一些内容。这是关于下面代码的问题。以下从某些队列实现中检索整数值的代码是否正确?答案是这样的:

Although the code above uses the queue as object monitor, it does not behave correctly in a multi-threaded environment. The reason for this is that it has two separate synchronized blocks. When two threads are woken up in line 6 by another thread that calls notifyAll(), both threads enter one after the other the second synchronized block. It this second block the queue has now only one new value, hence the second thread will poll on an empty queue and get null as return value.

我在想同步块(synchronized block)会阻止不同的线程同时访问这个资源,不是吗?谢谢。

public Integer getNextInt() {

Integer retVal = null;

synchronized (queue) {
try {
while (queue.isEmpty()) {
queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}

synchronized (queue) {
retVal = queue.poll();
if (retVal == null) {
System.err.println("retVal is null");
throw new IllegalStateException();
}
}

return retVal;
}

最佳答案

问题比您问题中描述的要广泛得多。它甚至不需要两个通知线程(或一个 notifyAll)就会陷入麻烦。问题是线程调度是不确定的。

考虑以下场景:

  • 线程 A 进入第一个 synchronized block ,找到一个空队列并等待
  • 另一个线程将一项放入队列并通知一个线程。
  • 线程 A 醒来并离开第一个同步 block
  • 线程 B 进入第一个 synchronized block 并发现一个非空队列并且不等待!
  • 线程 B 离开第一个同步 block

现在,两个线程,AB,即将进入第二个 synchronized block ,并且顺序并不重要,因为此时很明显,只有一个线程可以消耗一项,而另一个线程将失败(除非另一个线程恰好在中间将某些内容放入队列中)。

实际上,它甚至不需要任何通知,例如如果两个线程在队列仅包含一个元素时调用此方法。在尝试执行第二个 block 之前,它们都可能执行第一个发现队列非空的 block 。

<小时/>

底线是,如果您有某种条件,则执行该条件的 wait 的代码(意味着检查条件)和依赖于该条件的代码必须位于一个 synchronized block ,或者在其他类型的锁的情况下,必须在整个代码中持有锁。

关于java - 以下从某些队列实现中检索整数值的代码是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28028936/

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