黑马程序员技术交流社区

标题: 线程 wait方法 [打印本页]

作者: yin1031468524    时间: 2013-5-30 18:24
标题: 线程 wait方法
本帖最后由 yin1031468524 于 2013-5-31 12:08 编辑

wait方法可使本线程处于阻塞状态,让其他线程有机会有机会执行,如果其他的线程与之前的线程执行的设计同一块代码,那么它不也会执行wait()吗,那么notify就没机会被执行了,而notify()可以唤醒之前的线程,那么这样的话程序如何继续进行?
作者: ccywhut    时间: 2013-5-30 19:03
      sleep()是属于Thread类的方法,wait()、notify()和notifyAll()是根object的方法,它们所操控的是每个对象都会有的锁, 线程调用了wait()之后,会一直等下去,直到有别的线程调用了这个对象notify()或notifyAll()。
     你只能在synchronized方法或synchronized段里调用wait(),notify(),notifyAll(),否则程序运行时会抛出IllegalMonitorStateException。这个异常带着一个挺让人费解的“current thread not owner”消息。这个消息的意思是,如果线程调用对象的wait(),notify(),notifyAll(),必须先拥有这个对象的锁。调用notify()、notifyAll()方法后,被唤醒的唯一一个线程执行的第一条语句,是紧跟在wait()方法后面的语句。
     使用线程同步就行了,而且必须这么做[/color]
作者: ccywhut    时间: 2013-5-30 19:03
标题: 。。。
本帖最后由 ccywhut 于 2013-5-30 19:12 编辑

    。。。
作者: 赵乐    时间: 2013-5-30 19:16
所以 毕老师视频里面不是说了吗,notify() 是默认唤醒线程池中第一个等待的线程。  所以线程多的时候用notify(),如果遇到wait()  就是使线程全部wait(),线程就都不动了。。
这时候就用到notifyAll(), 把全部线程都唤醒,  
为什么定义notifyAll,
因为需要唤醒对方线程。
因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
你学到老毕的 生产消费那 就懂了。。

JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。

Lock:替代了Synchronized
        lock
        unlock
        newCondition()

Condition:替代了Object wait notify notifyAll
        await();
        signal();
        signalAll();

就可以实现本方线程只唤醒对方操作。


作者: Super_Class    时间: 2013-5-30 20:15
  1. class Resource{
  2.                                 String name;
  3.                                 String sex;

  4.                                  boolean flag = true;
  5.                                 public synchronized void put(String name,String sex){
  6.                                         if(!flag){
  7.                                                 try {
  8.                                                         wait();//当标志位为false,线程wait这里其实是r.wait();
  9.                                                 } catch (InterruptedException e1){}
  10.                                         }
  11.                                         this.name = name;
  12.                                         this .sex = sex;
  13.                                        
  14.                                         flag = false;        //执行完后,将标志位状态改变。
  15.                                         notify();                //并且唤醒一个线程这里其实是r.notify();
  16.                                 }
  17.                                
  18.                                 public synchronized void get(){
  19.                                         if(flag){
  20.                                                 try {
  21.                                                         wait();    //当标志位为true,线程wait。这里其实是r.wait();
  22.                                                 } catch (InterruptedException e1){}
  23.                                                 }
  24.                                         System.out.println(name+"....."+sex);
  25.                                        
  26.                                         flag = true;//执行完后,将标志位状态改变。
  27.                                         notify();//并且唤醒一个线程这里其实是r.notify();
  28.                                         }
  29.                                 }

  30.                                 class Input implements Runnable{
  31.                                         Resource r ;
  32.                                         private int x=0;
  33.                                         Input(Resource r){
  34.                                                 this.r = r;
  35.                                         }
  36.                                         public  void run(){   //这里有一个线程任务
  37.                                                 while(true){
  38.                                                         if(x == 0){
  39.                                                                 r.put("zhangsan","nan");//这里可以将同步代码封装
  40.                                                         }else{
  41.                                                                 r.put("lisi","nv");
  42.                                                         }
  43.                                                         x = (x+1)%2;
  44.                                                 }
  45.                                         }
  46.                                 }

  47.                                 class Output implements Runnable{
  48.                                         Resource r ;
  49.                                         Output(Resource r){
  50.                                                 this.r = r;
  51.                                         }
  52.                                        
  53.                                         public void run(){ //这里有一个线程任务
  54.                                                 while(true){
  55.                                                         r.get();        //这里可以将同步代码封装
  56.                                                 }
  57.                                         }
  58.                                 }
复制代码

作者: 殇_心。    时间: 2013-5-31 10:17
如果问题已解决,请及时修改分类,否则继续提问,谢谢合作!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2