英文:
this wait/notify code has abnormal performance
问题
看Java的wait/notify代码。我认为不会打印false。
但是,当我运行代码时,有时会打印false。
这是Java的一个bug吗?
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();
}
}
控制台输出结果:
false
false
false
英文:
look the java wait/notify code. I think, will not print false.
But, when I run the code, print false somtime.
Is it java bug?
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();
}
}
console result:
false
false
false
答案1
得分: 0
以下是翻译好的内容:
这种行为的原因被称为虚假唤醒。
线程可能会在没有notify()
调用的情况下停止等待并继续执行。这就是虚假唤醒 - 这是操作系统线程调度器的一种机制。
这就是为什么在调用wait()
之前始终要检查某些条件,并在调用notify()
之前显式地设置这些条件。不要单纯依赖notify()
本身来保证工作已完成。
示例:
线程 1
synchronized (lock) {
...
while (!condition) {
lock.wait();
}
...
}
线程 2
synchronized (lock) {
condition = true;
lock.notify();
}
英文:
The reason for such a behavior is called spurious wakeup.
Thread may stop waiting and continue it's execution without notify()
call. This is a spurious wakeup - a mechanism of operation system thread scheduler.
That's why you always check some condition before calling wait()
and set it explicitly before calling notify()
. Do not use notify()
itself as a guarantee of a job being done.
Example:
Thread 1
synchronized (lock) {
...
while (!condition) {
lock.wait();
}
...
}
Thread 2
synchronized (lock) {
condition = true;
lock.notify();
}
专注分享java语言的经验与见解,让所有开发者获益!
评论