黑马程序员技术交流社区

标题: 出错了!!! [打印本页]

作者: ↙五线谱╲    时间: 2013-12-2 20:51
标题: 出错了!!!
class Res
{        
        String name;
        String sex;
        boolean flag=false;
}
class  Input  implements Runnable
{
        private Res r;
        Input(Res r)
        {
                this.r=r;
        }
        public void run()
        {
                int x=0;   //b=true;
                while(true)
                {        if(r.flag)
                                wait();
                        synchronized(r)
                        {
                        if(x==0)        //if(b=ture)
                        {
                        r.name="徐成林";
                        r.sex="男";
                                //b=false;
                        }else{
                        r.name="紫萱";
                        r.sex="女";
                                //b=true
                        }
                        r.flag=true;
                        notify();
                        }
                        x=(x+1)%2;
                }
        }
}        
class Output implements Runnable
{
        private Res r;
        Output(Res r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {
                        if(r.flag)
                                wait();
                        synchronized(r)
                        {
                        System.out.println(r.name+"..."+r.sex);
                        }
                        r.flag=false;
                        notify();
                }        
        }
}
class   InputOutputDemo
{
        public static void main(String[] args)
        {
                Res r=new Res();
                Input in=new Input(r);
                Output out=new Output(r);
               
                Thread t1=new Thread(in);
                Thread t2=new Thread(out);

                t1.start();
                t2.start();
        }
}
复制代码
程序如上,我是跟着毕老师的视频一步步敲出来的。可是为什么还是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中!!!麻烦各位大侠帮忙看下问题所在!!!
作者: 黑马伍哲沂    时间: 2013-12-2 21:50
  1. package com.itheima.test;



  2. class Input implements Runnable {
  3.         private Res r;

  4.         Input(Res r) {
  5.                 this.r = r;
  6.         }

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

  34. class Output implements Runnable {
  35.         private Res r;
  36.         Output(Res r) {
  37.                 this.r = r;
  38.         }
  39.         public void run(){
  40.                 while (true) {
  41.                         synchronized (r) {
  42.                                 if (!r.flag)
  43.                                         try {
  44.                                                 r.wait();
  45.                                         } catch (InterruptedException e) {
  46.                                                 e.printStackTrace();
  47.                                         }
  48.                                 System.out.println(r.name + "..." + r.sex);
  49.                                 r.flag = false;
  50.                                 r.notify();
  51.                         }
  52.                 }
  53.         }
  54. }

  55. public class ForumQuestion {
  56.         public static void main(String[] args) {
  57.                 Res r = new Res();
  58.                 Input in = new Input(r);
  59.                 Output out = new Output(r);

  60.                 Thread t1 = new Thread(in);
  61.                 Thread t2 = new Thread(out);

  62.                 t1.start();
  63.                 t2.start();
  64.         }
  65. }


  66. class Res {
  67.         String name;
  68.         String sex;
  69.         boolean flag = false;
  70. }
复制代码

判断标记和等待唤醒的逻辑要写到同步代码里.

作者: 汪洋大海    时间: 2013-12-2 22:41
本帖最后由 汪洋大海 于 2013-12-2 22:48 编辑

你的代码,我改了半天改不正确。。把我的笔记给你看一下吧。希望对你有帮助。。
  1. /*
  2. 等待唤醒机制。
  3. wait()                        必须被锁调用,只用于多线程。会抛异常,wait后释放锁。 当锁是this时可以省略不写
  4. notify()                必须被锁调用,只用于多线程。当锁是this时可以省略不写
  5. notifyAll()                必须被锁调用,只用于多线程。当锁是this时可以省略不写

  6. 需求:定义两个线程,一个线程写数据,一个线程取数据。写一个取一个。

  7. 心得:两个线程用的是同一个对象,所以用的是同一个Demo对象作为锁。也就是this。
  8.           

  9. */
  10. class ThreadDemo7
  11. {
  12.         public static void main(String[] args)
  13.         {
  14.                 Demo d = new Demo();
  15.                
  16.                 new Thread(new Input(d)).start();
  17.                 new Thread(new Output(d)).start();

  18.         }
  19. }

  20. class Demo//取数据和改数据都在这个类中。
  21. {
  22.         private String name;
  23.         private String sex;
  24.         private boolean flag = false;

  25.         Object obj = new Object();

  26.         public synchronized void set(String name,String sex)//改数据。
  27.         {
  28.                
  29.                 if(!flag)
  30.                 {
  31.                         this.name = name;
  32.                         this.sex = sex;                       
  33.                         flag = true;
  34.                         this.notify();
  35.                 }
  36.                                
  37.                 try{this.wait();}catch(Exception ex){}
  38.         }

  39.         public synchronized void get()//取数据。
  40.         {
  41.                
  42.                 if(flag)
  43.                 {
  44.                         System.out.println(name+"----"+sex);                       
  45.                         flag = false;
  46.                         this.notify();
  47.                 }
  48.                
  49.                 try{this.wait();}catch(Exception ex){}
  50.         }
  51. }

  52. class Input implements Runnable
  53. {
  54.         private Demo d;
  55.         Input(Demo d)
  56.         {
  57.                 this.d = d;
  58.         }
  59.         public void run()
  60.         {
  61.                 while (true)
  62.                 {
  63.                         d.set("zhangsan","nan");
  64.                         d.set("李四","女");
  65.                 }               
  66.         }
  67. }

  68. class Output implements Runnable
  69. {
  70.         private Demo d;
  71.         Output(Demo d)
  72.         {
  73.                 this.d = d;
  74.         }
  75.         public void run()
  76.         {
  77.                 while (true)
  78.                 {
  79.                         d.get();
  80.                 }
  81.                
  82.         }
  83. }
复制代码




作者: 刘敏    时间: 2013-12-3 00:01
本帖最后由 刘敏 于 2013-12-3 00:03 编辑

class Res
{        
        String name;
        String sex;
        boolean flag=false;
}
class  Input  implements Runnable
{
        private Res r;
        Input(Res r)
        {
                this.r=r;
        }
        public void run()
        {
                int x=0;   //b=true;
                while(true)
                {       // if(r.flag)  --放入同步代码块
                         //       wait();--不能放在这里, 放入同步代码块,wait()函数的要求

                        synchronized(r)
                        {
                           if(r.flag)  //--放入同步代码块
                              try{ r.wait();} catch(Exception e){} //--放入同步代码块,要用唯一资源加锁,默认是this.wait(),不行。要用try包起来
                        if(x==0)        //if(b=ture)
                        {
                        r.name="徐成林";
                        r.sex="男";
                                //b=false;
                        }else{
                        r.name="紫萱";
                        r.sex="女";
                                //b=true   
                        }
                        r.flag=true;//--放入同步代码块
                        r.notify();//--放入同步代码块,notify()函数的要求,要用唯一资源加锁,默认是this.notify(),不行
                        }
                        x=(x+1)%2;
                }
        }
}        
class Output implements Runnable
{
        private Res r;
        Output(Res r)
        {
                this.r=r;
        }
        public void run()
        {
                while(true)
                {

                        synchronized(r)
                        {
                        if(!r.flag)
                               try{ r.wait();} catch(Exception e){}//同上
                        System.out.println(r.name+"..."+r.sex);
                        r.flag=false;//同上,放入同步代码块
                        r.notify();//同上,放入同步代码块
                        }

                }        
        }
}
class   InputOutputDemo
{
        public static void main(String[] args)
        {
                Res r=new Res();
                Input in=new Input(r);
                Output out=new Output(r);

                Thread t1=new Thread(in);
                Thread t2=new Thread(out);

                t1.start();
                t2.start();
        }
}


作者: 简★零度    时间: 2013-12-5 22:51
下次问题解决了就把类型改成提问结束!谢谢!




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