zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    获得 Web Service 方法的描述信息
    make menuconfig 报错
    汇编调用c函数为什么要设置栈
    UBoot Makefile文件分析
    UBoot启动过程完全分析(转)
    (转)在fedora12下用crosstoolng建立armlinux交叉编译环境
    UBoot编译过程完全分析(转)
    雷军:给互联网创业者的“七字”建议
    uboot根目录下makefile
    Redhat 5 配置Samba服务器
  • 原文地址:https://www.cnblogs.com/xumaomao/p/12843683.html
Copyright © 2011-2022 走看看