Java wait()、notify()、notifyAll()方法

wait()

调用wait()方法后,线程进入等待状态,wait()方法不会返回,直到将来某个时刻,线程从等待状态被其他线程唤醒后,wait()方法才会返回,然后,继续执行下一条语句。

wait()方法的执行机制非常复杂,它不是一个普通的Java方法,而是定义在Object类的一个native方法,也就是由JVM的C代码实现的。

必须在synchronized块中才能调用wait()方法,因为wait()方法调用时,会释放线程获得的锁wait()方法返回后,线程又会重新试图获得锁。

notify()、notifyAll()

this.notifyAll()将唤醒所有当前正在this锁等待的线程,而this.notify()只会唤醒其中一个(具体哪个依赖操作系统,有一定的随机性)。这是因为可能有多个线程正在getTask()方法内部的wait()中等待,使用notifyAll()将一次性全部唤醒。通常来说,notifyAll()更安全。有些时候,如果我们的代码逻辑考虑不周,用notify()会导致只唤醒了一个线程,而其他线程可能永远等待下去醒不过来了。

但是,注意到wait()方法返回时需要重新获得this锁。假设当前有3个线程被唤醒,唤醒后,首先要等待执行addTask()的线程结束此方法后,才能释放this锁,随后,这3个线程中只能有一个获取到this锁,剩下两个将继续等待。

实例

class TaskQueue {
    Queue<String> queue = new LinkedList<>();

    public synchronized void addTask(String s) {
        this.queue.add(s);
        this.notifyAll();
    }

    public synchronized String getTask() throws InterruptedException {
        while (queue.isEmpty()) {
            this.wait();    
        }
        return queue.remove();
    }
}

参考资料

廖雪峰Java

原文地址:https://www.cnblogs.com/xumaomao/p/12843683.html