java - 此等待/通知代码性能异常
问题描述
查看java等待/通知代码。我想,不会打印假的。但是,当我运行代码时,有时会打印错误。它是java错误吗?
public class TestThread {
public static volatile String lock = "111";
public static volatile AtomicBoolean flag = new AtomicBoolean(true);
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
try {
while (true) {
synchronized (lock) {
flag.compareAndSet(true, false);
lock.wait();
if (!flag.get()) {
System.out.println(flag.get());
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
flag.compareAndSet(false, true);
lock.notify();
}
}
}
}).start();
}
}
控制台结果:假假假
解决方案
这种行为的原因称为虚假唤醒。
线程可能会停止等待并继续执行而无需 notify()
调用。这是一个虚假的唤醒- 操作系统线程调度程序的一种机制。
这就是为什么你总是在调用之前检查一些条件wait()
并在调用之前明确设置它notify()
。不要将notify()
其本身作为工作完成的保证。
例子:
线程 1
synchronized (lock) {
...
while (!condition) {
lock.wait();
}
...
}
线程 2
synchronized (lock) {
condition = true;
lock.notify();
}