为何wait()和notify()属于Object类

关于wait()暂停的是持有锁的对象,因此想调用wait()必须为:对象.wait();this

notify()唤醒的是等待锁的对象,调用:对象.notify();线程

以下:对象

Object obj = newObject();接口

synchronized(obj){资源

    try{  同步

      obj.wait();it

      }catch(Exception e){}io

      obj.notify();jdk

  }object

注意:wait(),notify(),notifyAll()都必须使用在同步中,由于要对持有监视器(锁)的线程操做。因此要使用在同步中,由于只有同步 才具备锁。

为何这些操做线程的方法要定义在object类中呢?

简单说:由于synchronized中的这把锁能够是任意对象,因此任意对象均可以调用wait()和notify();因此wait和notify属于Object。

专业说:由于这些方法在操做同步线程时,都必需要标识它们操做线程的锁,只有同一个锁上的被等待线程,能够被同一个锁上的notify唤醒,不能够对不一样锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。而锁能够是任意对象,因此能够被任意对象调用的方法是定义在object类中。

 

在jdk1.5之后,将同步synchronized替换成了Lock,将同步锁对象换成了Condition对象,而且Condition对象能够有多个,这样能够解决一个问题。

好比说咱们在多个生产者和消费者模式中:

boolean flag = false;

public synchronized void set(String name){

  while(flag){//用while而不用if的缘由,这样每一个线程在wait等待醒来后都必须再次判断flag

    try{this.wait();}catch(Exception e){}  

    Sytem.out.printLn("生产者");

    flag = true;

    this.notifyAll();//这将唤醒全部线程(本方线程和对方线程),消耗资源

  }

}

public synchronized void out(){

  whie(!flag){

     try{this.wait();}catch(Exception e){}

    Sytem.out.printLn("消费者");

    flag = false;

    this.notifyAll();//这将唤醒全部线程(本方线程和对方线程),消耗资源

  }

}

上面的作法很消耗资源,若是把notifyAll()改为notify()的话,就会形成可能全部线程都在等待

 

因此在jdk1.5之后提供了Lock接口和Condition对象。Condition中的await(), signal().signalAll()代替Object中的wait(),notify(),notifyAll()

private Lock lock = new ReentrantLock();

private Condition condition_pro = lock.newCondition();//生产者对象

private Condition condition_con = lock.newCondition();//消费者对象

public void set(String name) throws Exception{

  lock.lock();//加锁

  try{

    while(flag){

     contion_pro.await();

     Sytem.out.printLn("生产者");

       flag= true;

     condition_con.singal();//指定唤醒消费方

   }finally{

    lock.unlock();//解锁    

    }  

  }

}

public void out() throws Exception{

  lock.lock();

  try{

    while(!flag){

       condition_con.await(); 

       Sytem.out.printLn("消费者");

       flag = false;

       condition_pro.signal();//指定唤醒生产方

      }finally{

      lock.unlock();  

      }

    }

}

这样作的好处,咱们能够指定唤醒某一方,减小消耗

相关文章
相关标签/搜索