首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

Wait 跟 Notify

2012-09-06 
Wait 和 Notifywait,notify,notifyAll 是Object的方法,用于线程间(确切的讲是需要使用同一个锁的线程间)的

Wait 和 Notify
wait,notify,notifyAll 是Object的方法,用于线程间(确切的讲是需要使用同一个锁的线程间)的通信.只有该对象锁的owner线程才可以调用这几个方法,否则会抛出异常.

1.wait() ,wait(sometime)

  该方法会使当前线程释放已经获得的锁,进入对该锁的等待状态(wait状态),在如下几种情况下才能重新进入(blocked)状态
   a.另外一个线程调用了该对象的notify方法,且该线程被选中
   b.另外一个线程调用了该对象的notifyAll方法
   c.过了指定的时间(通过wait(xxx)调用)
   d.另外一个线程调用了该线程的interrupt方法

另外还可能出现所谓的spurious wakeup情况,该情况在实际情况中非常罕见,但是最保险的方法还是把wait方法放入循环中,当程序期待的条件没有出现时,确保线程是wait状态的

      synchronized (obj) {
            while (condition is false){
                  obj.wait(timeout);
             }
              // Perform action appropriate to condition
          }
wait方法一般用于当线程期待的某个条件没有出现无法往下执行时,这个时候就要释放锁,给别的线程使用锁的机会注意,该方法只会释放被调用wait方法的对象,如果当前线程有多个锁,则其余的锁不会被释放,编码的时候要考虑这点.

2.notify,notifyAll
   
     notify只会唤醒一个waiting线程,如果有多个线程在waiting在这个对象锁时,就有可能你想唤醒的线程没有被唤醒(比如有一个消费者和一个生产者waiting在锁上,另外一个生产者调用notify本意唤醒消费者时,但是很有可能把生产者唤醒,造成死锁,所以尽量使用notiyAll,或者Condition来区分)[
 
    该方法会唤醒等待这个对象的线程,告诉它们锁马上就要释放了.区别是notify只随机选取一个线程,notifyAll会唤醒所有等待该对象的线程.

需要主要的是 当前线程调用notify或者notifyAll后并不会马上释放锁,什么时候释放,释放与否都是要根据实际的代码要决定,这点要切记.如下面代码,lock永远不会释放.所以编码时一定要在正确的时机调用notify和notifyAll:当前线程的工作已经完成或者部分完成,需要其余等待该锁的线程的配合才能继续时,可以调用该方法给其余的线程获得锁的使用权的机会.

   synchronized(lock){
       notify();
       while(true){
          System.out.println("I will never release the lock.."); 
       }
   }


通过上述解释,我们知道wait notify用于线程间的通信,达到正确执行并发程序的目的!

热点排行