首页 > 解决方案 > 此等待/通知代码性能异常

问题描述

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

控制台结果:假假假

标签: javamultithreadinglockingwaitnotify

解决方案


这种行为的原因称为虚假唤醒

线程可能会停止等待并继续执行而无需 notify()调用。这是一个虚假的唤醒- 操作系统线程调度程序的一种机制。

这就是为什么你总是在调用之前检查一些条件wait()并在调用之前明确设置它notify()。不要将notify()其本身作为工作完成的保证。

例子:

线程 1

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

线程 2

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

推荐阅读