java - 该等待/通知代码性能异常

标签 java multithreading locking wait notify

查看 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() 调用。这是spurious wakeup - 操作系统线程调度机制。

这就是为什么您总是在调用 wait() 之前检查某些条件,并在调用 notify() 之前显式设置它。不要使用 notify() 本身作为工作完成的保证。

示例:

主题 1

synchronized (lock) {
    ...
    while (!condition) {
        lock.wait();
    }
    ...
}

主题 2

synchronized (lock) {
    condition = true;
    lock.notify();
}

关于java - 该等待/通知代码性能异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61040593/

相关文章:

java - Elasticsearch 聚合查询没有给出预期的输出

multithreading - 由于另一个 QThread,QApplication 线程卡住

MySQL 错误 1205 : Lock wait timeout exceeded

安卓安全解锁信号

Java上传百分比进度条线程

java - 与 JPanel 不同对象中的字体尺寸

node.js - Nodejs 工作线程可以用于执行长时间运行的基于文件 I/O 的 JavaScript 代码吗?

java - 迭代 HashMap 时出现 ConcurrentModificationException

java - Spring Integration - 跨步骤共享锁

java - 为什么我的递归不起作用?