这段等待/通知的代码性能异常。

huangapple 未分类评论42阅读模式
英文:

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();
}

huangapple
  • 本文由 发表于 2020年4月5日 17:34:38
  • 转载请务必保留本文链接:https://java.coder-hub.com/61040593.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定