Java中对象的wait () notify () notifyAll()方法使用

  

<强> 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()方法使用