<强> Java中对象的等待()通知()notifyAll()方法使用强>
<强>一、前言强>
对于并发编程而言,除了线程以外,对对象对象的wati和通知对象也应该深入了解其用法,虽然知识点不多。
<强>二、线程安全基本知识强>
首先应该记住以下基本点,先背下来也无妨:
同一时间一个锁只能被一个线程持有调用对象的wait()和notify()前必须持有它
<强>三,wait()和notify()理解强>
<强> 3.1 wait()和notify()方法简介强>
wait()和notify()都是对象的方法,可以认为任意一个对象都是一种资源(或者资源的一个代表),当多个线程对一个资源进行操作时,如果线程发现这个资源还没有准备好,它就可以在这个资源上进行等待,即调用这个资源的等待()方法,如果有另外的线程经过某些处理觉得这个资源可用了,会调用这个这个资源的通知()方法,告诉等待它的线程,这个资源可以用了。
当然不使用wait()和notify()方法也是可以的,可以用在()死循环来判断,如下面的伪代码:
类资源{ 静态的布尔可以=false; } 而(! Resource.canUse) {//如果不可用,死循环在这里等待 }//当资源可以使用后,就会跳出循环,往下执行
这样做是可以,但是特别消耗CPU资源,所以建议用户使用wait()和notify()方法。
<强> 3.2 wait()和notify()的价值强>
其实从单词意思来看就能看出来,就等是等待,说明这个资源没有准备好,我要等,还有这一个等待(长超时),表示我只能等待你这么长时间了,过时不候啊,而调用通知()的线程肯定就是对资源进行处理的,处理完进行通知。所以呢,它们就经常用在生产者和消费者模式中。任何涉及等资源到来的情景都适合用这两个方法,
<强> 3.3为什么wait()和notify()必须和同步一起使用
强>
当不在同步同步块中使用wait()和notify()或者调用方法的对象不是同步的同步锁就会抛异常:
java.lang.IllegalMonitorStateException
很多人会疑惑为什么必须持有这个对象的锁才能调用对象的wait()和notify()方法呢,我也有这个疑惑,而且我认为这么做是没有必要的。首先看下面的代码:
公开课等{//这是一个资源,模拟的对象 最后NoObjct资源=new NoObjct (); 公共静态void main (String [] args){抛出异常 等待d=新等(); d.test (); } 公共空白测试()抛出异常{ 可运行r=新Runnable () { 公共空间run () {//调用资源的模拟的等待方法,在方法内部使用同步 resource.noWait (); System.out.println(“线程等待完,执行”); } }; 线程t=新线程(r); t.start (); thread . sleep (2000); System.out.println(“准备唤醒等待资源的线程”);//调用资源的模拟的通知方法,在方法内部使用同步 resource.noNotify (); } }//因wait()和notify()是最终的方法,不能覆盖,所以模拟一个对象对象 类NoObjct {//模拟等方法 公共空间noWait () {//这个就相当于将同步放到等待方法内部 同步(){ 尝试{ this.wait (); }捕捉(InterruptedException e) { e.printStackTrace (); } } }//模拟通知方法 公共空间noNotify () {//这个就相当于将同步放到通知方法内部 同步(){ this.notify (); } } }
这是一个简单的wait()和notify()例子,等等等,待通知唤醒。如果忽略掉模拟的对象会发现代码简洁了许多,否则就要每次使用同步,如下代码:
公开课等{//这是一个资源,模拟的对象 最终对象资源=新对象(); 公共静态void main (String [] args){抛出异常 等待d=新等(); d.test (); } 公共空白测试()抛出异常{ 可运行r=新Runnable () { 公共空间run () {//必须使用同步 尝试{ 同步(资源){ resource.wait (); } }捕捉(InterruptedException e) { e.printStackTrace (); } System.out.println(“线程等待完,执行”); } }; 线程t=新线程(r); t.start (); thread . sleep (2000); System.out.println(“准备唤醒等待资源的线程”);//必须使用同步 同步(资源){ resource.notify (); } } }Java中对象的wait () notify () notifyAll()方法使用