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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 揭耀祖 中级黑马   /  2012-5-27 15:50  /  1778 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 jxj4227982333 于 2012-5-27 15:59 编辑

今天在复习多线程这块时发现了个小问题,是关于多线程间通信的。如下:

  1. class Input implements Runnable
  2. {
  3.       Res r;
  4.       Input(Res r)
  5.      {
  6.         this.r = r;
  7.      }
  8.         public void run()
  9.       {
  10.         int x = 0;
  11.                while(true)
  12.              {
  13.                  synchronized(r)     //当input持有锁进入后,output 是不能够进入同步代码块的,当然我的假设               
  14.                     {                       //是input先持有锁进来的output还没来的及判断锁更没有进入等待状态。
  15.                         if(r.flag)              
  16.                           try{r.wait();}catch(Exception e){}   //当input线程执行到这时,进入了等待状态后,它还持有锁啊,   
  17.                       if(x==0)                                              //output线程为什么还能够执行?难道是input进入等待状态
  18.                         {                                                       //后,不仅放弃了执行权,锁也不持有了吗  ?
  19.                            r.name = "小明";                                 
  20.                           r.sex = "男男男男男男";
  21.                         }
  22.                     else
  23.                       {
  24.                         r.name = "rose";
  25.                        r.sex = "female";
  26.                       }
  27.                         x=(x+1)%2;
  28.                        r.flag = true;
  29.                        r.notify();   
  30.                }

  31.           }
  32.      }

  33. }
  34. //////////////////////////////////////////////////////////////////////////////////////////////////
  35. class Output implements Runnable
  36. {
  37.        Res r;
  38.      Output(Res r)
  39.      {
  40.        this.r = r;
  41.     }
  42.        public void run()
  43.        {
  44.                 while(true)
  45.                 {

  46.                  synchronized(r)    //当input持有锁在执行的时候甚至进入等待状态后,output很可能还没有进入同步代码块啊
  47.                       {
  48.                             if(!r.flag)
  49.                           try{r.wait();}catch(Exception e){}
  50.                          System.out.println(r.name+"...."+r.sex);
  51.                           r.flag = false ;
  52.                          r.notify();
  53.                   }

  54.              }
  55.       }
  56. }
复制代码
我的问题都写在上面的注释里面了,谁来帮我把思路捋捋顺。


评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

2 个回复

倒序浏览
当多个线程使用同一个监视器时,如果某个线程先拿到监视器则其他线程无法进入同步代码块,但如果得到监视器的线程等待时即进入wait状态时不仅放弃了cpu执行权,同时还放弃了锁,这时其他线程就可以执行了,如果有个线程把wait的线程叫醒了的话它一旦获得cpu执行权就会开始执行,因为他已经进入同步代码块内部,不用再管锁在谁手里了。

点评

哦,果然和我猜想的一样!  发表于 2012-5-27 18:07
回复 使用道具 举报
  1. class  Duo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Res r = new Res();
  6.                 Thread t1 = new Thread(new Input(r));
  7.                 Thread t2 = new Thread(new Output(r));
  8.                 t1.start();
  9.                 t2.start();
  10.         }
  11. }

  12. class Res
  13. {
  14.         boolean flag = false;
  15.         String name;
  16.         String sex;
  17. }
  18. class Input implements Runnable

  19. {

  20.       Res r;

  21.       Input(Res r)

  22.      {

  23.         this.r = r;

  24.      }

  25.         public void run()

  26.       {
  27.         int x = 0;

  28.                while(true)

  29.              {
  30.                  synchronized(r)     //当input持有锁进入后,output 是不能够进入同步代码块的,当然我的假设               

  31.                     {                       //是input先持有锁进来的output还没来的及判断锁更没有进入等待状态。

  32.                         if(r.flag)              

  33.                           try{r.wait();}catch(Exception e){}   //当input线程执行到这时,进入了等待状态后,它还持有锁啊,   

  34.                       if(x==0)                                              //output线程为什么还能够执行?难道是input进入等待状态

  35.                         {                                                       //后,不仅放弃了执行权,锁也不持有了吗  ?

  36.                            r.name = "小明";                                 
  37.                           r.sex = "男男男男男男";

  38.                         }

  39.                     else

  40.                       {

  41.                         r.name = "rose";

  42.                        r.sex = "female";

  43.                       }

  44.                         x=(x+1)%2;

  45.                        r.flag = true;

  46.                        r.notify();   
  47.                }


  48.           }

  49.      }


  50. }

  51. //////////////////////////////////////////////////////////////////////////////////////////////////

  52. class Output implements Runnable

  53. {

  54.        Res r;

  55.      Output(Res r)

  56.      {

  57.        this.r = r;

  58.     }

  59.        public void run()

  60.        {
  61.                 while(true)

  62.                 {

  63.                  synchronized(r)    //当input持有锁在执行的时候甚至进入等待状态后,output很可能还没有进入同步代码块啊

  64.                       {

  65.                             if(!r.flag)

  66.                           try{r.wait();}catch(Exception e){}

  67.                          System.out.println(r.name+"...."+r.sex);

  68.                           r.flag = false ;

  69.                          r.notify();

  70.                   }


  71.              }

  72.       }

  73. }
复制代码
好吧,楼主,我必须说如果按照我加上的代码的话应该没问题,但是如果你在主函数里面是这样写的话就有问题了
  1. class  Duo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 //Res r = new Res();
  6.                 Thread t1 = new Thread(new Input(new Res()));
  7.                 Thread t2 = new Thread(new Output(new Res()));
  8.                 t1.start();
  9.                 t2.start();
  10.         }
  11. }
复制代码
如果是这样的话,两个线程根本不是用同样的锁,线程当然都可以各执行各的了!!楼主,是你调用的问题吧?

点评

当然是Res r = new Res()了。  发表于 2012-5-27 18:06
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马