写点什么

Java 线程中的 wait、notify 和 notifyAll 解析

作者:共饮一杯无
  • 2023-04-19
    浙江
  • 本文字数:1556 字

    阅读完需:约 5 分钟

Java线程中的wait、notify和notifyAll解析

Java 中的线程有六种状态,具体可以查看我之前的文章:https://xie.infoq.cn/article/873a38a88ac00594a1998c965。本文主要讲其中的部分状态切换。

等待唤醒案例:线程间的通信



顾客去包子铺买包子,告知老板自身需求后,进入等待(调用 wait()方法)老板处理的过程,此时顾客的状态为 WAITING,老板做好包子后,告知(调用 notify()方法)顾客包子做好了。💡线程间的通信的主要思想是生产者消费者机制。

代码实现

思路如下:


  1. 创建一个顾客线程(消费者):告知老板要的包子的种类和数量,调用 wait 方法,放弃 CPU 的执行,进入到 WAITING 状态(无限等待)

  2. 创建一个老板线程(生产者):花了 5 秒做包子,做好包子之后,调用 notify 方法,唤醒顾客吃包子。


代码如下:定义一个锁对象:


//创建锁对象,保证唯一Object obj = new Object();
复制代码


创建一个顾客线程(消费者):


// 创建一个顾客线程(消费者)new Thread(){    @Override    public void run() {        //一直等着买包子        while(true){            //保证等待和唤醒的线程只能有一个执行,需要使用同步技术            synchronized (obj){                System.out.println("顾客告知老板要的包子的种类和数量");                //调用wait方法,放弃cpu的执行,进入到WAITING状态(无限等待)                try {                    obj.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }                //唤醒之后执行的代码                System.out.println("包子已经做好了,开吃!");                System.out.println("---------------------------------------");            }        }    }}.start();
复制代码


创建一个老板线程(生产者):


//创建一个老板线程(生产者)new Thread(){    @Override    public void run() {        //一直做包子        while (true){            //花了5秒做包子            try {                Thread.sleep(5000);//花5秒钟做包子            } catch (InterruptedException e) {                e.printStackTrace();            }
//保证等待和唤醒的线程只能有一个执行,需要使用同步技术 synchronized (obj){ System.out.println("老板5秒钟之后做好包子,告知顾客,可以吃包子了"); //做好包子之后,调用notify方法,唤醒顾客吃包子 obj.notify(); } } }}.start();
复制代码


输出如下:


顾客告知老板要的包子的种类和数量

老板 5 秒钟之后做好包子,告知顾客,可以吃包子了

包子已经做好了,开吃!

---------------------------------------

顾客告知老板要的包子的种类和数量

老板 5 秒钟之后做好包子,告知顾客,可以吃包子了

包子已经做好了,开吃!

---------------------------------------

💡注意:顾客和老板线程必须使用同步代码块包裹起来,保证等待和唤醒只能有一个在执行同步使用的锁对象必须保证唯一只有锁对象才能调用 wait 和 notify 方法。

扩展:Object 类中 wait 带参方法和 notifyAll 方法

进入到 TimeWaiting(计时等待)有两种方式


  1. 使用 sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到 Runnable/Blocked 状态

  2. 使用 wait(long m)方法,wait 方法如果在毫秒值结束之后,还没有被 notify 唤醒,就会自动醒来,线程睡醒进入到 Runnable/Blocked 状态


唤醒的方法:


  • void notify() 唤醒在此对象监视器上等待的单个线程。

  • void notifyAll() 唤醒在此对象监视器上等待的所有线程。


本文内容到此结束了,

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

主页共饮一杯无的博客汇总👨‍💻

保持热爱,奔赴下一场山海。🏃🏃🏃

发布于: 刚刚阅读数: 3
用户头像

鲜衣怒马意气风发,愿你归来仍是少年。 2018-10-19 加入

全栈开发者,CSDN博客专家,51CTO 专家博主,阿里云专家博主,华为云享专家,持续输出干货,欢迎关注。

评论

发布
暂无评论
Java线程中的wait、notify和notifyAll解析_Java_共饮一杯无_InfoQ写作社区