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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM汪磊 高级黑马   /  2013-3-13 23:42  /  1621 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM汪磊 于 2013-3-14 12:38 编辑
  1. 疑问代码中注释。
  2. import java.util.concurrent.locks.*;

  3. class ProducerConsumerDemo2
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 Resource r = new Resource();

  8.                 Producer pro = new Producer(r);
  9.                 Consumer con = new Consumer(r);

  10.                 Thread t1 = new Thread(pro);
  11.                 Thread t2 = new Thread(pro);
  12.                 Thread t3 = new Thread(con);
  13.                 Thread t4 = new Thread(con);

  14.                 t1.start();
  15.                 t2.start();
  16.                 t3.start();
  17.                 t4.start();

  18.         }
  19. }

  20. class Resource
  21. {
  22.         private String name;
  23.         private int count = 1;
  24.         private boolean flag = false;
  25.                         //  t1    t2
  26.         private Lock lock = new ReentrantLock();//Lock是接口,类ReentrantLock 实现接口Lock ,接口不是不能创建对象吗??

  27.         private Condition condition_pro = lock.newCondition();//这两句话不明白,请各位解释一下???
  28.         private Condition condition_con = lock.newCondition();



  29.         public  void set(String name)throws InterruptedException
  30.         {
  31.                 lock.lock();
  32.                 try
  33.                 {
  34.                         while(flag)
  35.                                 condition_pro.await();//凭什么说condition_pro.await()就指定的是让生产者等待???有什么依据???
  36.                         this.name = name+"--"+count++;

  37.                         System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  38.                         flag = true;
  39.                         condition_con.signal();//凭什么说condition_con.signal() 就指定的是唤醒消费者???有什么依据???
  40.                 }
  41.                 finally
  42.                 {
  43.                         lock.unlock();//释放锁的动作一定要执行。
  44.                 }
  45.         }


  46.         //  t3   t4  
  47.         public  void out()throws InterruptedException
  48.         {
  49.                 lock.lock();
  50.                 try
  51.                 {
  52.                         while(!flag)
  53.                                 condition_con.await();
  54.                         System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
  55.                         flag = false;
  56.                         condition_pro.signal();
  57.                 }
  58.                 finally
  59.                 {
  60.                         lock.unlock();
  61.                 }
  62.                
  63.         }
  64. }

  65. class Producer implements Runnable
  66. {
  67.         private Resource res;

  68.         Producer(Resource res)
  69.         {
  70.                 this.res = res;
  71.         }
  72.         public void run()
  73.         {
  74.                 while(true)
  75.                 {
  76.                         try
  77.                         {
  78.                                 res.set("+商品+");
  79.                         }
  80.                         catch (InterruptedException e)
  81.                         {
  82.                         }
  83.                         
  84.                 }
  85.         }
  86. }

  87. class Consumer implements Runnable
  88. {
  89.         private Resource res;

  90.         Consumer(Resource res)
  91.         {
  92.                 this.res = res;
  93.         }
  94.         public void run()
  95.         {
  96.                 while(true)
  97.                 {
  98.                         try
  99.                         {
  100.                                 res.out();
  101.                         }
  102.                         catch (InterruptedException e)
  103.                         {
  104.                         }
  105.                 }
  106.         }
  107. }


复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

6 个回复

倒序浏览
本帖最后由 猫腻 于 2013-3-14 09:36 编辑
  1. class Resource
  2. {
  3.         private String name;
  4.         private int count = 1;
  5.         private boolean flag = false;
  6.                         //  t1    t2//类ReentrantLock这个不是接口,可以new
  7.         private Lock lock = new ReentrantLock();//Lock是接口,类ReentrantLock 实现接口Lock ,接口不是不能创建对象吗??
  8.        //把 Condition 对象绑定到一个叫lock锁对象上,API解释:
  9.     Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,
  10.       为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
  11.       个人理解:当线程在某个condition.await下等待的,他必须由其他线程执行同一个condition的notify,notifyAll才能才唤醒。
  12.         private Condition condition_pro = lock.newCondition();//这两句话不明白,请各位解释一下???
  13.         private Condition condition_con = lock.newCondition();



  14.         public  void set(String name)throws InterruptedException
  15.         {
  16.                 lock.lock();
  17.                 try
  18.                 {
  19.                         while(flag)//因为这段代码只有生者才执行的啊!消费都好像没有执行这部分代码吧!消费都执行的是下面的那部分代码啊
  20.                                 condition_pro.await();//凭什么说condition_pro.await()就指定的是让生产者等待???有什么依据???
  21.                         this.name = name+"--"+count++;

  22.                         System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  23.                         flag = true;//因为费消都执行了condition_con.await()了,下看面消费者所执行的代码,也就是说消者是在同一个锁condition_con这个条件下等待的
  24.                         condition_con.signal();//凭什么说condition_con.signal() 就指定的是唤醒消费者???有什么依据???
  25.                 }
  26.                 finally
  27.                 {
  28.                         lock.unlock();//释放锁的动作一定要执行。
  29.                 }
  30.         }


  31.         //  t3   t4  
  32.         public  void out()throws InterruptedException
复制代码

点评

每次看见你回答很认真,但要注意代码用编辑功能里的插入。  发表于 2013-3-14 09:36

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 turalyang@gmail 于 2013-3-14 00:54 编辑

1.Lock是接口,类ReentrantLock实现接口Lock ,接口不是不能创建对象吗??
答:Lock是接口,不能实例化,但经过实现的话就可以了。既然你知道"类ReentrantLock实现接口Lock" ,就应该明白ReentrantLock是Lock接口的实现类,它实现了接口中那些方法的方法体,而这条语句实例化的是这个实现类,而不是接口本身啦。。

2.
  1. private Condition condition_pro = lock.newCondition();     //这两句话不明白,请各位解释一下???
  2.        private Condition condition_con = lock.newCondition();
  3. /*
  4. 答:Condition实例实质上是被绑定到一个锁上,要为特定Lock实例获得Condition实例,就需要使用其newCondition()方法。
  5. 所以就有这样两条语句,意思是创建名为condition_pro和condition_con的Condition实例,并用private声明使其私有化。
  6. */
复制代码
3.
  1. try
  2.                 {
  3.                         while(flag)
  4.                                 condition_pro.await();//凭什么说condition_pro.await()就指定的是让生产者等待???有什么依据???
  5.                         this.name = name+"--"+count++;

  6.                         System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  7.                         flag = true;
  8.                         condition_con.signal();//凭什么说condition_con.signal() 就指定的是唤醒消费者???有什么依据???
  9.                 }
  10. /*
  11. 答:await()方法是这么一个功能:令当前线程在接到信号或被中断之前一直处于等待状态。
  12.     而signal()方法则是这样的功能:唤醒一个等待线程。
  13.     这都是Condition接口定义的方法,真要问为什么。。其实我也不知道。。
  14. */
复制代码
这个是貌似是JDK1.5添加的内容,其实就是Synchronized换成Lock,将Object中的wait,notify,notifyAll这些方法换成了Condition里头的await,signal,signalAll.

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 猫腻 于 2013-3-14 09:37 编辑

1、Lock是接口,类ReentrantLock 实现接口Lock ,接口不是不能创建对象吗?
接口不能用于创建实例,但接口可以用于声明引用类型的变量。当使用接口来声明引用类型的变量时,这个引用类型的变量必须是其实现类的对象。也因此有面向接口编程来降低程序的耦合。
private Condition condition_pro = lock.newCondition();
程序不使用synchronized关键字来保证线程同步而使用Lock对象来保证同步,则系统中就不存在隐式的同步监视器对象,也就不能使用wait、notify等方法来协调进程的运行。所以提供了一个Condition类来保持协调。Condition可以代替了同步监视器的功能。此处之所以定义两个是为了更好的协调。如果只定义一个Condition 这样唤醒线程的时候就可能唤醒和自己同类的线程。如当只有一个生产者1运行时其余三者都等待。
  1.     {                   while(flag)            
  2.                                        condition.await();  
  3.                       this.name = name+"--"+count++;      
  4. *                    System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);  
  5.                       flag = true;                     
  6.                        condition.signal();生产者1此时唤醒生产者2,1循环判断flag是等待,这是2执行判断flag也为true也等待这样四个线程就都等待了。   
  7. *           }
复制代码
2、而定义两个Condition:condition_pro、condition_con这样生产者1在唤醒其他线程时唤醒的肯定是消费者线程而不是生产者线程。

3、condition_pro.await();凭什么说condition_pro.await()就指定的是让生产者等待???有什么依据???                     
ondition_con.signal();//凭什么说condition_con.signal() 就指定的是唤醒消费者???有什么依据???
这就相当于定义了两个数组condition_pro和ondition_con.。
当生产者判断Flag为true时执行condition_pro.await();就相当于把该生产者放入名为condition_pro的数组。当消费者执行condition_pro.signal();时就相当于从名为condition_pro数组中取出生产者。condition_pro和ondition_con.只是一个名字或标签,只是看你在执行await时把该线程存在那个数组中等待或打上相同的标签,这样signal时就可以根据名或者标签来唤醒线程

评分

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

查看全部评分

回复 使用道具 举报
这个问题在基础视频中应该讲到了,具体是那一天的课程我忘了。你可以再看看。
回复 使用道具 举报
楼主:如果还有问题,请追问,如果无问题,请结贴,谢谢合作。
回复 使用道具 举报
猫腻 发表于 2013-3-14 09:38
楼主:如果还有问题,请追问,如果无问题,请结贴,谢谢合作。

回答的加分,怎么提问的没分????唉。。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马