黑马程序员技术交流社区

标题: 线程中wait()为何报错有Exception了 [打印本页]

作者: 何超    时间: 2013-11-8 22:19
标题: 线程中wait()为何报错有Exception了
  1. class Res
  2. {       
  3.         String name;
  4.         String sex;
  5.         boolean flag=false;
  6. }
  7. class  Input  implements Runnable
  8. {
  9.         private Res r;
  10.         Input(Res r)
  11.         {
  12.                 this.r=r;
  13.         }
  14.         public void run()
  15.         {
  16.                 int x=0;   //b=true;
  17.                 while(true)
  18.                 {        if(r.flag)
  19.                                 wait();
  20.                         synchronized(r)
  21.                         {
  22.                         if(x==0)        //if(b=ture)
  23.                         {
  24.                         r.name="徐成林";
  25.                         r.sex="男";
  26.                                 //b=false;
  27.                         }else{
  28.                         r.name="紫萱";
  29.                         r.sex="女";
  30.                                 //b=true
  31.                         }
  32.                         r.flag=true;
  33.                         notify();
  34.                         }
  35.                         x=(x+1)%2;
  36.                 }
  37.         }
  38. }       
  39. class Output implements Runnable
  40. {
  41.         private Res r;
  42.         Output(Res r)
  43.         {
  44.                 this.r=r;
  45.         }
  46.         public void run()
  47.         {
  48.                 while(true)
  49.                 {
  50.                         if(r.flag)
  51.                                 wait();
  52.                         synchronized(r)
  53.                         {
  54.                         System.out.println(r.name+"..."+r.sex);
  55.                         }
  56.                         r.flag=false;
  57.                         notify();
  58.                 }       
  59.         }
  60. }
  61. class   InputOutputDemo
  62. {
  63.         public static void main(String[] args)
  64.         {
  65.                 Res r=new Res();
  66.                 Input in=new Input(r);
  67.                 Output out=new Output(r);
  68.                
  69.                 Thread t1=new Thread(in);
  70.                 Thread t2=new Thread(out);

  71.                 t1.start();
  72.                 t2.start();
  73.         }
  74. }
复制代码
程序如上,我是跟着毕老师的视频一步步敲出来的。可是为什么还是wait出错。实在搞不懂,我试着放进Eclipse里修改,修改了就是把两个wait()用try和catch捕捉,于是我试着按照提示修改并捕捉,然后运行的时候系统又报错Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalM
onitorStateException
at java.lang.Object.notify(Native Method)
at Input.run(InputOutputDemo.java:38)
at java.lang.Thread.run(Thread.java:722)
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at Output.run(InputOutputDemo.java:57)
at java.lang.Thread.run(Thread.java:722)

真心搞不懂到底哪里出错了  系统错误提示也是说在线程0和线程1中!!!麻烦各位大侠帮忙看下问题所在!!!

作者: FFF    时间: 2013-11-8 22:39
本帖最后由 FFF 于 2013-11-8 22:46 编辑

Wait没有明确的指向。Wait,你要wait谁,要说清楚。只要把Wait()前面加上个this就可以了!
  1. try{this.wait();}catch(Exception e){}//Wait改
复制代码
贴上我的代码,给你参考一下!
  1. package temp;
  2. class Res
  3. {
  4.         private String name;
  5.         private String sex;
  6.         boolean flag= false ;
  7.         public synchronized void ste(String name,String sex)
  8.         {
  9.                 if(flag)
  10.                         try{this.wait();}catch(Exception e){}
  11.                 this.name=name;
  12.                 this.sex=sex;
  13.                 flag=true;
  14.                 this.notify();
  15.         }
  16.         public synchronized void out()
  17.         {
  18.                 if(!flag)
  19.                         try{this.wait();}catch(Exception e){}
  20.                 System.out.println(name+"Is"+sex);
  21.                 flag=false;
  22.                 this.notify();
  23.         }
  24. }
  25. class Input implements Runnable
  26. {
  27.         private Res r;
  28.         Input(Res r)
  29.         {
  30.                 this.r = r;
  31.         }
  32.         public void run()
  33.         {
  34.                 int x= 0;
  35.                 int close = 0;
  36.                 while(close<20)
  37.                 {
  38.                         if(x==0)
  39.                                 r.ste("贝克","Man");
  40.                         else
  41.                                 r.ste("安吉","lady");
  42.                         x= (x+1)%2;                       
  43.                         close++;
  44.                 }
  45.         }
  46. }
  47. class Output implements Runnable
  48. {
  49.         private Res r;
  50.         private int close1=0;
  51.         Output(Res r)
  52.         {
  53.                 this.r=r;
  54.         }
  55.         public void run()
  56.         {
  57.                 while(close1<20)
  58.                 {
  59.                         r.out();
  60.                         close1++;
  61.                 }
  62.         }
  63. }
  64. public class Temp10_24多线程通信_唤醒机制 {

  65.         public static void main(String[] args)
  66.         {
  67.                 Res r = new Res();
  68.                 new Thread(new Input(r)).start();
  69.                 new Thread(new Output(r)).start();
  70.                 /*
  71.                 Input in = new Input(r);
  72.                 Output ou = new Output(r);
  73.                
  74.                 Thread t1 = new Thread(in);
  75.                 Thread t2 = new Thread(ou);
  76.                
  77.                 t1.start();
  78.                 t2.start();
  79.                 */
  80.         }
  81. }
复制代码

作者: 秦久启    时间: 2013-11-8 22:57
上面说的很对,第一个你是没有对wait()进行异常处理,try一下就可以了,第二个就是Wait没有明确的指向
作者: zuiaichiyu    时间: 2013-11-8 22:58
锁的位置加错了,线程一进入while循环 就应该拿锁,在判断是否等待,如果flag为false,说明目标中没有内容,线程不用等待,这时向目标添加内容,将标记改为true,并唤醒等待的线程。如果flag为true,说明目标中有内容,此时线程等待,wait()肯定会产生异常,你没有处理,this可以省略不写
作者: Uncle.Lee    时间: 2013-11-8 23:07
上面说的都不是最重要的,最重要的是wait()  notify() 这些操作线程的方法要放在同步语句快内

你的代码还没上锁 就开始用他们了,还有50行的if的条件应该是if(!r.flag)

下面附上我写的代码,给你参考下
class Resource {
        String name;
        String sex;
        boolean flag = false;
}

class Input implements Runnable {
        Resource res;

        public Input(Resource res) {
                this.res = res;
        }

        public void run() {
                int num = 0;
                while (true) {
                        synchronized (res) {
                                if (res.flag) {
                                        try {
                                                res.wait();
                                        } catch (Exception e) {
                                                System.out.println(e.toString());
                                        }
                                } else {
                                        if (num == 0) {
                                                res.name = "mike";
                                                res.sex = "man";
                                        } else {
                                                res.name = "莉莉";
                                                res.sex = "女女";
                                        }
                                        num = (num + 1) % 2;
                                        res.flag = true;
                                        res.notify();
                                }
                        }
                }
        }
}

class OutPut implements Runnable {
        Resource res;

        public OutPut(Resource res) {
                this.res = res;
        }

        public void run() {
                while (true) {
                        synchronized (res) {
                                if (!res.flag) {
                                        try {
                                                res.wait();
                                        } catch (Exception e) {
                                                System.out.println(e.toString());
                                        }
                                } else {
                                        System.out.println(res.name + "---" + res.sex);
                                        res.flag = false;
                                        res.notify();
                                }
                        }

                }
        }
}

public class SwapMessage {
        public static void main(String[] args) {
                Resource res = new Resource();
                Input in = new Input(res);
                OutPut out = new OutPut(res);
                Thread th1 = new Thread(in);
                Thread th2 = new Thread(out);
                th1.start();
                th2.start();

        }
}


作者: FFF    时间: 2013-11-8 23:09
本帖最后由 FFF 于 2013-11-8 23:13 编辑

终于帮你把代码改好了!
好多错误啊!!!!愁死我了都!
  1. class Res {
  2.         String name;
  3.         String sex;
  4.         boolean flag = false;
  5. }

  6. class Input implements Runnable {
  7.         private Res r;

  8.         Input(Res r) {
  9.                 this.r = r;
  10.         }

  11.         public void run() {
  12.                 int x = 0; // b=true;
  13.                 while (true) {
  14.                         synchronized (r) {
  15.                         if (r.flag)
  16.                                         try{r.wait();}catch(Exception e){}
  17.                         
  18.                                 if (x == 0) // if(b=ture)
  19.                                 {
  20.                                         r.name = "徐成林";
  21.                                         r.sex = "男";
  22.                                         // b=false;
  23.                                 } else {
  24.                                         r.name = "紫萱";
  25.                                         r.sex = "女";
  26.                                         // b=true
  27.                                 }
  28.                                 r.flag = true;
  29.                                 r.notify();
  30.                         }
  31.                         x = (x + 1) % 2;

  32.                 }
  33.         }
  34. }

  35. class Output implements Runnable {
  36.         private Res r;

  37.         Output(Res r) {
  38.                 this.r = r;
  39.         }

  40.         public void run() {
  41.                 while (true) {
  42.                         synchronized (r){
  43.                         if (!r.flag)
  44.                                         try{r.wait();}catch(Exception e){}
  45.                         
  46.                                 System.out.println(r.name + "..." + r.sex);
  47.                         
  48.                         r.flag = false;
  49.                         r.notify();
  50.                 }
  51.                 }
  52.         }
  53. }

  54. class Temp1Day {
  55.         public static void main(String[] args) {
  56.                 Res r = new Res();
  57.                 Input in = new Input(r);
  58.                 Output out = new Output(r);
  59.                
  60.                 Thread t1 = new Thread(in);
  61.                 Thread t2 = new Thread(out);
  62.                 t1.start();
  63.                 t2.start();
  64.         }
  65. }
复制代码
主要错误:
1.Wait没有指向。
2.锁synchronized (r)加在了if里面。应该是if在synchronized (r)里面的

(让你把锁挂厕所门上别让人进来,你直接把锁丢厕所马桶里。能不出错吗?'开玩笑,别介意啊~~')

同学,你应该多看几次代码的!

作者: 何超    时间: 2013-11-8 23:23
FFF 发表于 2013-11-8 23:09
终于帮你把代码改好了!
好多错误啊!!!!愁死我了都!主要错误:
1.Wait没有指向。

太感谢你了!!!:handshake
作者: 何超    时间: 2013-11-8 23:32
FFF 发表于 2013-11-8 23:09
终于帮你把代码改好了!
好多错误啊!!!!愁死我了都!主要错误:
1.Wait没有指向。

但是毕老师的视频里他没有抛出异常也正确运行了啊  为嘛




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