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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ぺsimon☆ 中级黑马   /  2013-5-17 17:05  /  1519 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. /*
  2. 生产者和消费者的升级版
  3. java新特性

  4. 问题是:
  5.         private Condition condition_in=lock.newCondition();
  6.         private Condition condition_out=lock.newCondition();

  7. 上面两个Condition怎么知道是属于那个线程的呢?好像程序也没有标记那个Condition是属于生产者还是消费者的啊?
  8. 到底是怎么区分的呢兄弟?

  9. condition_in.await();等待的是生产者的线程
  10. condition_out.signal();唤醒消费者的线程

  11. condition_out.await();等待的是消费者的线程
  12. condition_in.await();唤醒生产者的线程
  13. */

  14. import java.util.concurrent.locks.*;
  15. class Res3
  16. {
  17.         private String name;
  18.         private String sex;
  19.         private boolean flag=false;
  20.         private Lock lock=new ReentrantLock();

  21.         private Condition condition_in=lock.newCondition();
  22.         private Condition condition_out=lock.newCondition();

  23.         public void setRes(String name,String sex)throws InterruptedException
  24.         {

  25.                 lock.lock();

  26.                 //这里写try{}finally{}是为了避免当发生异常的时候,保证可以线程释放锁
  27.                 try
  28.                 {
  29.                 while(flag)

  30.                 //让生产者wait
  31.                    condition_in.await();
  32.                 this.name=name;
  33.                 this.sex=sex;
  34.                 System.out.println(Thread.currentThread().getName()+"生产者"+name+"..."+sex);

  35.                 flag=true;
  36.                 //这里用notifyAll唤醒所有线程,避免唤醒的是本方线程,注意如果用notify,它唤醒的是进入线程       

  37.         池中的第一个线程,有可能唤醒的是本方线程,造成所有的线程都在等待               

  38.                 //叫醒消费者
  39.                 condition_out.signal();
  40.                 }

  41.                 finally
  42.                 {
  43.                         lock.unlock();
  44.                 }
  45.         }

  46.         public void getRes()throws InterruptedException
  47.         {

  48.                 lock.lock();
  49.                 try
  50.                 {
  51.                 //当flag为false时消费者就等待,否则就消费
  52.                 while(!flag)
  53.                   condition_out.await();

  54.                 System.out.println(Thread.currentThread().getName()+"消费者"+name+"-----"+sex);
  55.                 flag=false;
  56.                 condition_in.signal();
  57.                 }

  58.                 finally
  59.                 {
  60.                         lock.unlock();
  61.                 }
  62.         }
  63. }

  64. class Input3 implements Runnable
  65. {

  66.         private Res3 r;
  67.         Input3(Res3 r)
  68.         {
  69.                 this.r=r;
  70.         }

  71.         public void run()
  72.         {
  73.                 int x=0;
  74.                 while(true)
  75.                 {
  76.                         if(x==0)
  77.                         {
  78.                                
  79.                                 try{r.setRes("mike","man");}catch(Exception e){}
  80.                         }

  81.                         try{r.setRes("丽丽","女");}catch(Exception e){}
  82.                         x=(x+1)%2;
  83.                 }
  84.         }       
  85. }

  86. class Output3 implements Runnable
  87. {
  88.         private Res3 r;
  89.         Output3(Res3 r)
  90.         {
  91.                 this.r=r;
  92.         }

  93.         public void run()
  94.         {
  95.                 while(true)
  96.                 try{r.getRes();}catch(Exception e){}
  97.         }
  98. }

  99. class InputOutputDemo3
  100. {
  101.         public static void main(String[] args)
  102.         {
  103.                 Res3 r=new Res3();
  104.                 Input3 in=new Input3(r);
  105.                 Output3 out=new Output3(r);

  106.                 Thread t1=new Thread(in);
  107.                 Thread t2=new Thread(in);

  108.                 Thread t3=new Thread(out);
  109.                 Thread t4=new Thread(out);

  110.                 t1.start();
  111.                 t2.start();
  112.                 t3.start();
  113.                 t4.start();
  114.         }
  115. }
复制代码

评分

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

查看全部评分

5 个回复

倒序浏览
这个不用标记的 就是两个变量
生产者中用condition_out.signal();唤醒消费者,是因为消费者中用condition_out.await();等待的
同理 :消费者中用condition_in.signal();唤醒生产者,是因为生产者中是用condition_in.await();等待的

在变量定义的时候我们事先指定哪一个要在生产者里面用哪一个要在消费者中用,所以起个名字。如果你两两进行交换一样可以的

评分

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

查看全部评分

回复 使用道具 举报
"上面两个Condition怎么知道是属于那个线程的呢?"
个人理解:其实应该说是哪个线程属于某个condition,
condition 处于哪个线程中,则该线程就属于哪个condition;
例如:某一线程执行到condition_xx.await();则该线程就属于condition_xx

评分

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

查看全部评分

回复 使用道具 举报
condition_in.await();  这个地方就是监视器特有的方法。满足条件,线程就冻结(相当于一个监视器设定了一个线程池,一个监视器冻结的方法只放在对应的线程池中)
   condition_in.signal();
condition_out.signal();
这两个唤醒的肯定不是一个线程。

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 郭军亮 于 2013-5-18 10:15 编辑

上面两个Condition怎么知道是属于那个线程的呢?"
这个是在你创建线程的时候自己传给线程的
定义的线程应该是这样的Threa t=new Thread(out);
Threa t=new Thread(in);这样就这道了哪个线程该等待,哪个该唤醒了。。。。

评分

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

查看全部评分

回复 使用道具 举报
郭军亮 发表于 2013-5-17 22:42
上面两个Condition怎么知道是属于那个线程的呢?"
这个是在你创建线程的时候自己传给线程的
定义的线程应该 ...

如果没有传进去,该怎么区分呢哥们,视频里没有传进去的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马