A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李道福 中级黑马   /  2013-9-10 20:07  /  1676 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李道福 于 2013-9-10 23:29 编辑
  1. class Resource{
  2.         String name;
  3.         int age;
  4.         boolean flag=false;
  5.         Resource(){}
  6.         Resource(String name,int age){
  7.                 this.name=name;
  8.                 this.age=age;
  9.         }
  10. }

  11. class Input implements Runnable{
  12.         Resource s=null;
  13.         Input(Resource s){
  14.                 this.s=s;
  15.         }
  16.         public void run(){
  17.                 int x=0;
  18.                 while(true)
  19.                 synchronized(s){
  20.                         if(s.flag)
  21.                                 try{s.wait();}catch(Exception e){}//这里如果我把s.wait()改成wait(),程序运行的结果就和之前不一样了
  22.           if(x%2==0){
  23.                                 s.name="lidaofu";
  24.                                 s.age=24;
  25.                         }else{
  26.                                 s.name="李道福";
  27.                                 s.age=23;
  28.                         }
  29.                         x=(x+1)%2;
  30.                         s.flag=true;
  31.                         s.notify();
  32.                 }
  33.         }
  34. }

  35. class Output implements Runnable{
  36.         Resource s=null;
  37.         Output(Resource r){
  38.                 this.s=r;
  39.         }
  40.         public void run(){
  41.                 while(true)
  42.                 synchronized(s){
  43.                         if(!s.flag)
  44.                                 try{s.wait();}catch(Exception e){}
  45.                         System.out.println(s.name+"++++++"+s.age);
  46.                         s.flag=false;
  47.                         s.notify();
  48.                 }
  49.         }
  50. }


  51. public class ProduConsume{
  52.         public static void main(String[] args){
  53.                 Resource r=new Resource();
  54.                 Input in=new Input(r);
  55.                 Output out=new Output(r);
  56.                
  57.                 Thread th=new Thread(in);
  58.                 Thread th2=new Thread(out);
  59.                 th.start();
  60.                 th2.start();
  61.         }
  62. }
复制代码
这里的s.wait()和s.notity()等待,唤醒的是s这个线程池中的线程,那如果我改成wait(),那这个wait()把线程放在那个线程池中的?

评分

参与人数 1技术分 +1 收起 理由
EYE_SEE_YOU + 1

查看全部评分

6 个回复

倒序浏览
一定要指定对象才可以等待吧,否则的话,多线程,就不一定是哪个线程抢到wait执行权······
回复 使用道具 举报
好像只写 wait的话, 不论哪个线程碰到,都要等待.  
回复 使用道具 举报
如果你把wait()上的锁去掉的话,就会出现同步嵌套,非静态默认的锁是this,wait(),notify(),notifyAll()这些方法在使用的时候必须指定线程所持有监视器(锁),因为只有同一个监视器上的被等待线程,可以被同一个监视器上的notify()唤醒,不可以对不同锁中的线程进行唤醒,所以必须使用同一个监视器(锁)对象来调用这些方法。
回复 使用道具 举报
这里的s相当于同步中的监视器
如果wait()前面没有s这类似的监视器的话,那么就不能保证输入域输出线程之间的同步,可能存在安全问题
如果是这样的话,使用wait方法也就没什么作用
回复 使用道具 举报
wait()方法是Object中的方法,也就是说在调用wait方法的时候需要加上监视器对象,不然的话就成了这个类在调用wait()方法了,也就是相当于程序中的Input.wait()  
这时候就会报wait()的所有者不是监视器对象这个异常了,而你在这里对这个异常做了处理,所以程序会继续运行下去,只不过相当于wait()这个方法是无效的 如果在异常处理语句中加上处理内容,就很容易看出来了

try{wait();}catch(Exception e){System.out.println("fda");
                                e.printStackTrace();}

回复 使用道具 举报
李政 发表于 2013-9-10 23:11
wait()方法是Object中的方法,也就是说在调用wait方法的时候需要加上监视器对象,不然的话就成了这个类在调 ...

多谢……
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马