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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 罗广伟 中级黑马   /  2013-6-13 17:44  /  2140 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 罗广伟 于 2013-6-14 10:24 编辑
  1. class Resource
  2. {
  3.         private String name;
  4.         private int count = 1;
  5.         private boolean flag = false;
  6.         private Lock lock = new ReentrantLock();
  7.         private Condition condition_pro = lock.newCondition();
  8.         private Condition condition_con = lock.newCondition();
  9.         public  void set(String name)throws InterruptedException
  10.         {
  11.                 lock.lock();
  12.                 try
  13.                 {
  14.                         while(flag)
  15.                                 condition_pro.await();
  16.                         this.name = name+"--"+count++;
  17.                         System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  18.                         flag = true;
  19.                         condition_con.signal();
  20.                 }
  21.                 finally
  22.                 {
  23.                         lock.unlock();//释放锁的动作一定要执行。
  24.                 }
  25.         }
  26.         public  void out()throws InterruptedException
  27.         {
  28.                 lock.lock();
  29.                 try
  30.                 {
  31.                         while(!flag)
  32.                                 condition_con.await();
  33.                         System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
  34.                         flag = false;
  35.                         condition_pro.signal();
  36.                 }
  37.                 finally
  38.                 {
  39.                         lock.unlock();
  40.                 }
  41.                
  42.         }
  43. }
复制代码
问题位置:12天06,问题内容:condition_pro.signal();是如何被识别为是唤醒生产者线程而不是消费者线程的。

评分

参与人数 1技术分 +1 收起 理由
Super_Class + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
这两步就定义好了的,生产者线程和消费者线程,唤醒就可以用名字来识别
回复 使用道具 举报
        Lock 实现提供了比使用 synchronized
                                方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。
                                 
                                Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock
                                实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了
                                Object 监视器方法的使用
                               
                                对比以上示例:
                                使用了一个锁,两个监视器。目的是,实现线程间的同步(互斥)。唤醒机制,只唤醒需要监视器中的线程对象
                                        public void put(String name){
                                                lock.lock(); //直接在这里加了锁,相当于家里synshronized将函数同步
                                                try{
                                                        while(flag)                                //这里使用的是监视器con1的await()方法       
                                                                try {con1.await();} catch (InterruptedException e){ e.printStackTrace();}               
                                                                this.name = name+count;
                                                                count++;
                                                                System.out.println(Thread.currentThread().getName()+"...Producer..........s"+this.name);
                                                                flag = true;
                                                                // notifyAll();
                                                                con2.signal();        //这里使用的是监视器的signal,唤醒消费者线程(任意一个)。
                                                }
                                                finally{
                                                        lock.unlock();                //锁用完了就要释放掉
                                                }
                                               
                                        }
                                       
                                        public void get(){
                                                lock.lock();
                                                try{
                                                        while(!flag)        //这里使用的是监视器con2的await()方法       
                                                                try {con2.await();} catch (InterruptedException e){e.printStackTrace();}
                                                                 System.out.println(Thread.currentThread().getName()+"...xiaofeile...."+name);
                                                                flag = false;
                                                                // notifyAll();
                                                                con1.signalAll();//这里使用的是监视器的signal,唤醒生产者线程(任意一个)。
                                                }
                                                finally{
                                                        lock.unlock();
                                                }
                                        }
                                 }
                 
                                上边示例中出现了Lock接口:替代了同步代码块或者同步函数。将同步的隐式操作变成显示锁,
                                并且更加灵活。(可以使用多组监视器)
回复 使用道具 举报
Super_Class 发表于 2013-6-13 18:18
Lock 实现提供了比使用 synchronized
                                方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构 ...

可能我回答的还不够清晰:如果多个线程操作一个线程任务。最好就是用1.5的新特性Lock

否则很容易产生死锁
回复 使用道具 举报
Super_Class 发表于 2013-6-13 18:23
可能我回答的还不够清晰:如果多个线程操作一个线程任务。最好就是用1.5的新特性Lock

否则很容易产生死 ...

我想了想是不是,con1.await和con1.signal都属于con1对象,是成对出现的,con1.signal唤醒的是con1.await。所以con1.signal唤醒的是哪个线程要看con1.await定义在那个线程里面。
回复 使用道具 举报
曹世明 发表于 2013-6-13 18:13
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newC ...

我想了想是不是,con1.await和con1.signal都属于con1对象,是成对出现的,con1.signal唤醒的是con1.await。所以con1.signal唤醒的是哪个线程要看con1.await定义在那个线程里面。
回复 使用道具 举报
罗广伟 发表于 2013-6-14 09:43
我想了想是不是,con1.await和con1.signal都属于con1对象,是成对出现的,con1.signal唤醒的是con1.await ...

差不这样理解:con1.await()  将当前线程放入到con1这个线程池中。
                     con1.signal() 唤醒的是con1池子中的随机的一个线程。
回复 使用道具 举报
Super_Class 发表于 2013-6-14 09:51
差不这样理解:con1.await()  将当前线程放入到con1这个线程池中。
                     con1.signal()  ...

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