Java 条件不成立时线程唤醒的混淆原因
我目前正在阅读有效Java,我在并发一章。在解释当一个条件不成立时线程可能会被唤醒的原因(While循环中wait()调用的条件)时,有一个原因让我非常困惑,我似乎无法理解 另一个线程可能已经获得了锁,并在线程调用notify和等待线程唤醒之间更改了保护状态Java 条件不成立时线程唤醒的混淆原因,java,multithreading,concurrency,Java,Multithreading,Concurrency,我目前正在阅读有效Java,我在并发一章。在解释当一个条件不成立时线程可能会被唤醒的原因(While循环中wait()调用的条件)时,有一个原因让我非常困惑,我似乎无法理解 另一个线程可能已经获得了锁,并在线程调用notify和等待线程唤醒之间更改了保护状态 有人能解释一下这个句子吗?这是最容易用一个例子来解释的: public class ConditionTest implements Runnable { private boolean flag; pu
有人能解释一下这个句子吗?这是最容易用一个例子来解释的:
public class ConditionTest implements Runnable {
private boolean flag;
public void run() {
try {
synchronized (this) {
while (true) {
this.wait();
if (flag) {
System.out.printf("%s: my condition is true\n",
Thread.currentThread().getName());
flag = false;
} else {
System.out.printf("%s: my condition is false!!\n",
Thread.currentThread().getName());
}
}
}
} catch (InterruptedException ex) {
// bail out
}
}
public static void main(String[] args) throws InterruptedException {
ConditionTest ct = new ConditionTest();
new Thread(ct).start();
new Thread(ct).start();
new Thread(ct).start();
Thread.sleep(1000);
while (true) {
synchronized(ct) {
ct.flag = true;
ct.notifyAll();
}
Thread.sleep(1000);
}
}
}
本例中的条件是runnable的标志
应为true
。工作线程报告条件的状态,然后清除标志
如您所见,main方法创建并启动了三个共享runnable的线程。然后,它重复将标志设置为true并通知工人
当工作人员被唤醒时,它可能会发现该标志为false
;i、 它的状况不成立。事实上,如果您运行上述代码,您将看到三次中有两次发生这种情况
为什么?
因为,如果工作程序看到标志==true
,它将清除该标志!所以当其他工人醒来时,他们看到了被清除的旗帜
这就是引用的文本所谈论的那种事情
诚然,在这种情况下,它是由我们可疑的notifyAll
调用引起的,但一般原则适用。你应该检查一下情况
在某些平台上也可能(或曾经)发生虚假通知;i、 e.不是来自应用程序代码的任何
notify
或notifyAll
调用的结果的通知。这是最容易用一个示例解释的:
public class ConditionTest implements Runnable {
private boolean flag;
public void run() {
try {
synchronized (this) {
while (true) {
this.wait();
if (flag) {
System.out.printf("%s: my condition is true\n",
Thread.currentThread().getName());
flag = false;
} else {
System.out.printf("%s: my condition is false!!\n",
Thread.currentThread().getName());
}
}
}
} catch (InterruptedException ex) {
// bail out
}
}
public static void main(String[] args) throws InterruptedException {
ConditionTest ct = new ConditionTest();
new Thread(ct).start();
new Thread(ct).start();
new Thread(ct).start();
Thread.sleep(1000);
while (true) {
synchronized(ct) {
ct.flag = true;
ct.notifyAll();
}
Thread.sleep(1000);
}
}
}
本例中的条件是runnable的标志
应为true
。工作线程报告条件的状态,然后清除标志
如您所见,main方法创建并启动了三个共享runnable的线程。然后,它重复将标志设置为true并通知工人
当工作人员被唤醒时,它可能会发现该标志为false
;i、 它的状况不成立。事实上,如果您运行上述代码,您将看到三次中有两次发生这种情况
为什么?
因为,如果工作程序看到标志==true
,它将清除该标志!所以当其他工人醒来时,他们看到了被清除的旗帜
这就是引用的文本所谈论的那种事情
诚然,在这种情况下,它是由我们可疑的notifyAll
调用引起的,但一般原则适用。你应该检查一下情况
在某些平台上也可能(或曾经)发生虚假通知;i、 e.不是来自应用程序代码的任何
notify
或notifyAll
调用的结果的通知