文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

浅谈Java线程间通信之wait/notify

2023-05-31 12:27

关注

Java中的wait/notify/notifyAll可用来实现线程间通信,是Object类的方法,这三个方法都是native方法,是平台相关的,常用来实现生产者/消费者模式。先来我们来看下相关定义:

wait() :调用该方法的线程进入WATTING状态,只有等待另外线程的通知或中断才会返回,调用wait()方法后,会释放对象的锁。

wait(long):超时等待最多long毫秒,如果没有通知就超时返回。

notify() :通知一个在对象上等待的线程,使其从wait()方法返回,而返回的前提是该线程获取到了对象的锁。

notifyAll():通知所有等待在该对象上的线程。

一个小例子

我们来模拟个简单的例子来说明,我们楼下有个小小的饺子馆,生意火爆,店里有一个厨师,一个服务员,为避免厨师每做好一份,服务员端出去一份,效率太低且浪费体力。现假设厨师每做好10份,服务员就用一个大木盘子端给客户,每天卖够100份就打烊收工,厨师服务员各自回家休息。

思考一下,要实现该功能,如果不使用等待/通知机制,那么最直接的方式可能就是,服务员隔一段时间去厨房看看,满10份就用盘子端出去。

这种方式有两个很大的弊病:

如果服务员去厨房看的太勤快,服务员太累了,这样还不如每做一碗就端一碗给客人,大木盘子的作用就体现不出来了。具体表现在实现代码层面就是:需要不断的循环,浪费处理器资源。

如果服务员隔很久才去厨房看一下,就无法确保及时性了,可能厨师早都做够10份了,服务员却没观察到。

针对上面这个例子,使用等待/通知机制就合理的多了,厨师每做够10份,就喊一声“饺子好了,可以端走啦”。服务员收到通知,就去厨房将饺子端给客人;厨师还没做够,即还没收到厨师的通知,就可以稍微休息下,但也得竖起耳朵等候厨师的通知。 

package ConcurrentTest;import thread.BlockQueue;public class JiaoziDemo {  //创建个共享对象做监视器用  private static Object obj = new Object();  //大木盘子,一盘最多可盛10份饺子,厨师做满10份,服务员就可以端出去了。  private static Integer platter = 0;  //卖出的饺子总量,卖够100份就打烊收工  private static Integer count = 0;    static class Cook implements Runnable{    @Override    public void run() {      while(count<100){        synchronized (obj){          while (platter<10){            platter++;          }          //通知服务员饺子好了,可以端走了          obj.notify();          System.out.println(Thread.currentThread().getName()+"--饺子好啦,厨师休息会儿");        }        try {          //线程睡一会,帮助服务员线程抢到对象锁          Thread.sleep(100);        } catch (InterruptedException e) {          e.printStackTrace();        }      }      System.out.println(Thread.currentThread().getName()+"--打烊收工,厨师回家");    }  }    static class Waiter implements Runnable{    @Override    public void run() {      while(count<100){        synchronized (obj){          //厨师做够10份了,就可以端出去了          while(platter < 10){            try {              System.out.println(Thread.currentThread().getName()+"--饺子还没好,等待厨师通知...");              obj.wait();              BlockQueue            } catch (InterruptedException e) {              e.printStackTrace();            }          }          //饺子端给客人了,盘子清空          platter-=10;          //又卖出去10份。          count+=10;          System.out.println(Thread.currentThread().getName()+"--服务员把饺子端给客人了");        }      }      System.out.println(Thread.currentThread().getName()+"--打烊收工,服务员回家");    }  }  public static void main(String []args){    Thread cookThread = new Thread(new Cook(),"cookThread");    Thread waiterThread = new Thread(new Waiter(),"waiterThread");    cookThread.start();    waiterThread.start();  }}

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯