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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 yting_xmei1129 于 2013-10-12 23:42 编辑

下面是代码、、、
  1. package yting.day11.thread;

  2. import java.util.concurrent.locks.*;

  3. public class LockCondition_ProducerConsumerDemo1 {

  4.         public static void main(String[] args) {
  5.                 Resource_all res = new Resource_all();
  6.                
  7.                 //两个生产者
  8.                 new Thread(new Producer_all(res)).start();
  9.                 new Thread(new Producer_all(res)).start();
  10.                
  11.                 //两个消费者
  12.                 new Thread(new Consumer_all(res)).start();
  13.                 new Thread(new Consumer_all(res)).start();
  14.                
  15.         }

  16. }

  17. class Resource_all {
  18.         private String name;
  19.         private int count = 1;
  20.         private boolean flag = false;
  21.         private Lock lock = new ReentrantLock();
  22.         private Condition cond = lock.newCondition();
  23.         
  24.         public synchronized void setName(String name) {
  25.                 lock.lock();
  26.                 try {
  27.                         while (flag) {
  28.                                 cond.await();        
  29.                         }
  30.                         this.name = name + "---" + count++;
  31.                         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
  32.                         flag = true;
  33.                         cond.signalAll();
  34.                 } catch (InterruptedException e) {
  35.                         e.printStackTrace();
  36.                 } finally {
  37.                         lock.unlock();
  38.                 }
  39.         }
  40.         
  41.         public synchronized void print(){
  42.                 lock.lock();
  43.                 try {
  44.                         while (!flag) {
  45.                                 cond.await();
  46.                         }
  47.                         System.out.println(Thread.currentThread().getName() + "...消费者.........." + name);
  48.                         flag = false;
  49.                         cond.signalAll();
  50.                 } catch (InterruptedException e) {
  51.                         e.printStackTrace();
  52.                 } finally {
  53.                         lock.unlock();
  54.                 }
  55.         }

  56. }

  57. class Producer_all implements Runnable {
  58.         private Resource_all r;
  59.         
  60.         public Producer_all(Resource_all r) {
  61.                 this.r = r;
  62.         }
  63.         @Override
  64.         public void run() {
  65.                 while(true){
  66.                         r.setName("商品");
  67.                 }
  68.         }
  69. }

  70. class Consumer_all implements Runnable {
  71.         private Resource_all r;
  72.         
  73.         public Consumer_all(Resource_all r) {
  74.                 this.r = r;
  75.         }
  76.         @Override
  77.         public void run() {
  78.                 while(true){
  79.                         r.print();
  80.                 }
  81.         }
  82.         
  83. }
复制代码
运行的时候会一直等在那里,求大神解答,感激不尽、、、

评分

参与人数 1技术分 +1 收起 理由
黄文伯 + 1

查看全部评分

7 个回复

倒序浏览

RE: JAVA 多线程_线程通信_Lock & Condition 问题、、、

  1. /*生产者,消费者练习
  2. jdk1.5新特性:java.util.concurrent.lock包中
  3. 接口Lock(子类 ReentrantLock) :lock();  unlock()f方法  已替代了synchronized函数和synchronized代码块

  4. 一个锁机制支持多个Condition对象
  5. 接口Condition :awit();  signal();  signalAll()方法已替代wit();  notify();  notifyAll()方法

  6. 你的代码运行全部等待问题:是因为SignalAll不仅唤醒了本方线程,而且唤醒了对方线程造成的全部等待

  7. 第一个问题:
  8.   private Condition cond_1 = lock.newCondition();
  9. private Condition cond_2 = lock.newCondition();//建立多个condition,两组awiat()




  10. 第二个问题:
  11. public  void setName(String name) {//Lock 替代了synchronized函数[code]import java.util.concurrent.locks.*;

  12. public class LockCondition_ProducerConsumerDemo1 {

  13.         public static void main(String[] args) {
  14.                 Resource_all res = new Resource_all();
  15.                
  16.                 //两个生产者
  17.                 new Thread(new Producer_all(res)).start();
  18.                 new Thread(new Producer_all(res)).start();
  19.                
  20.                 //两个消费者
  21.                 new Thread(new Consumer_all(res)).start();
  22.                 new Thread(new Consumer_all(res)).start();
  23.                
  24.         }

  25. }

  26. class Resource_all {
  27.         private String name;
  28.         private int count = 1;
  29.         private boolean flag = false;
  30.         private Lock lock = new ReentrantLock();
  31.                
  32.         private Condition cond_1 = lock.newCondition();
  33.                 private Condition cond_2 = lock.newCondition();//修改1多个condition
  34.         
  35.         public  void setName(String name) {//Lock 替代了synchronized函数
  36.                 lock.lock();
  37.                 try {
  38.                         while (flag) {
  39.                                 cond_1.await();        
  40.                         }
  41.                         this.name = name + "---" + count++;
  42.                         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
  43.                         flag = true;
  44.                         cond_2.signal();
  45.                 } catch (InterruptedException e) {
  46.                         e.printStackTrace();
  47.                 } finally {
  48.                         lock.unlock();
  49.                 }
  50.         }
  51.         
  52.         public synchronized void print(){
  53.                 lock.lock();
  54.                 try {
  55.                         while (!flag) {
  56.                                 cond_2.await();
  57.                         }
  58.                         System.out.println(Thread.currentThread().getName() + "...消费者.........." + name);
  59.                         flag = false;
  60.                         cond_1.signal();
  61.                 } catch (InterruptedException e) {
  62.                         e.printStackTrace();
  63.                 } finally {
  64.                         lock.unlock();
  65.                 }
  66.         }

  67. }

  68. class Producer_all implements Runnable {
  69.         private Resource_all r;
  70.         
  71.         public Producer_all(Resource_all r) {
  72.                 this.r = r;
  73.         }
  74.         @Override
  75.         public void run() {
  76.                 while(true){
  77.                         r.setName("商品");
  78.                 }
  79.         }
  80. }

  81. class Consumer_all implements Runnable {
  82.         private Resource_all r;
  83.         
  84.         public Consumer_all(Resource_all r) {
  85.                 this.r = r;
  86.         }
  87.         @Override
  88.         public void run() {
  89.                 while(true){
  90.                         r.print();
  91.                 }
  92.         }
  93.         
  94. }
复制代码
[/code]

评分

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

查看全部评分

回复 使用道具 举报
我想应该是两个消费者线程都被冻结了而没有释放执行权
回复 使用道具 举报

原来只要把那个 synchronized 删除了就好了,这太不细心了、、、谢了
回复 使用道具 举报
楼主,你的程序的问题在于使用了同步:synchronized然后又使用了Lock和Condition接口,这两个接口是jdk1.5之后的版本,也让多线程同步变得更加的灵活,而你的代码中,Resource_all中使用的是同步函数,但在里面又用了Lock和Condition接口,但是synchronized只对应的是一个锁。而接口Lock和Condition可心对应多个锁,也可以唤醒指定的线程。所以,你的代码应该是出现死锁状态了,下面,我将同步和使用接口的代码分别发上来:
回复 使用道具 举报
  1. /*
  2. 线程间通信-生产者消费者

  3. 使用同步synchronized
  4. 唤醒其它线程用notify();
  5. */

  6. class  ProduceConsumerDemo
  7. {
  8.         public static void main(String[] args)
  9.         {
  10.                 Resource res=new Resource();
  11.                 new Thread(new Producer(res)).start();
  12.                 new Thread(new Producer(res)).start();
  13.                 new Thread(new Consumer(res)).start();
  14.                 new Thread(new Consumer(res)).start();
  15.         }
  16. }
  17. class Resource
  18. {
  19.         private String name;
  20.         private int count=1;//标记
  21.         private boolean flag=false;
  22.         //t1  t2
  23.         public synchronized/*使用同步*/ void set(String name)
  24.         {
  25.                 /*if*/while(flag)//这里不能用if()因为if()只能判断一次
  26.                 try{this.wait();}catch(InterruptedException e){}//t1(放弃资格)  t2(获取资格)
  27.         this.name=name+"---"+count++;//加上编号赋值
  28.         System.out.println(Thread.currentThread().getName()+"produce"+this.name);
  29.                 flag=true;
  30.                 notifyAll();//这里省略了this.
  31.                 /*
  32.                 上面的notifyAll()是唤醒所有线程,而楼主的代码中是用condition.signal()唤醒,
  33.                 但是注意,这是是用同步函数,所以,用notify来唤醒线程;
  34.                 */
  35.         }
  36.         //t3  t4
  37.         public synchronized void out()
  38.         {
  39.                 /*if*/while(!flag)
  40.         try{this.wait();}catch(InterruptedException e){}
  41.         System.out.println(Thread.currentThread().getName()+"消费者....."+this.name);
  42.                 flag=false;
  43.         notifyAll();
  44.        
  45.         }
  46. }
  47. //
  48. class Producer implements Runnable//生产
  49. {
  50.         private Resource res;
  51.         Producer(Resource r)
  52.         {
  53.         this.res=r;
  54.         }
  55.         public void run()
  56.         {
  57.         while(true)
  58.                 res.set("商品");
  59.         }

  60. }
  61. class Consumer implements Runnable//消费者
  62. {
  63.         private Resource res;
  64.          Consumer(Resource r)
  65.         {
  66.         this.res=r;
  67.         }
  68.         public void run()
  69.         {
  70.         while (true)
  71.         {
  72.                 res.out();
  73.         }
  74.         }
  75. }
复制代码
回复 使用道具 举报
王飚 中级黑马 2013-10-9 14:36:28
7#
  1. /*
  2. 线程间通信-生产者消费者_1

  3. 使用Lock和Condition接口实现多线程

  4. */
  5. import java.util.concurrent.locks.*;
  6. class  ProduceConsumerDemo_1
  7. {
  8.         public static void main(String[] args)
  9.         {
  10.                 Resource res=new Resource();
  11.                 new Thread(new Producer(res)).start();
  12.                 new Thread(new Producer(res)).start();
  13.                 new Thread(new Consumer(res)).start();
  14.                 new Thread(new Consumer(res)).start();
  15.         }
  16. }
  17. class Resource
  18. {
  19.         private String name;
  20.         private int count=1;//标记
  21.         private boolean flag=false;
  22.         private Lock lock=new ReentrantLock();//  返回绑定到此 Lock 实例的新 Condition 实例。
  23.         private Condition condition_pro=lock.newCondition();
  24.         private Condition condition_con=lock.newCondition();
  25.         //注意:下面就不需要同步函数synchronized
  26.         public  void set(String name) throws InterruptedException
  27.         {
  28.                 lock.lock();
  29.                 try
  30.                 {
  31.                         while(flag)
  32.                         condition_pro.await();
  33.                         this.name=name+"---"+count++;
  34.         System.out.println(Thread.currentThread().getName()+"produce"+this.name);
  35.                 flag=true;
  36.                 condition_con.signal();//唤醒消费者等待线程
  37.                 }
  38.                 finally
  39.                 {
  40.                 lock.unlock();//无论是否有InterruptedException异常,都要释放锁
  41.                 }
  42.         }
  43.         public  void out() throws InterruptedException
  44.         {
  45.                 lock.lock();
  46.                 try{
  47.                         while(!flag)
  48.                         condition_con.await();//消费者线程冻结
  49.                         System.out.println(Thread.currentThread().getName()+"消费者....."+this.name);
  50.                         flag=false;
  51.                         condition_pro.signal();//唤醒生产者线程
  52.                 }
  53.                 finally
  54.                 {
  55.                 lock.unlock();
  56.                 }
  57.         }
  58. }
  59. class Producer implements Runnable
  60. {
  61.         private Resource res;
  62.         Producer(Resource r)
  63.         {
  64.         this.res=r;
  65.         }
  66.         public void run()
  67.         {
  68.         while(true)
  69.                 try
  70.                 {
  71.                         res.set("商品");
  72.                 }
  73.                 catch (InterruptedException e)
  74.                 {
  75.                 }
  76.         }
  77. }
  78. class Consumer implements Runnable
  79. {
  80.         private Resource res;
  81.          Consumer(Resource r)
  82.         {
  83.         this.res=r;
  84.         }
  85.         public void run()
  86.         {
  87.         while (true)
  88.         {
  89.                 try
  90.                 {
  91.                         res.out();
  92.                 }
  93.                 catch (InterruptedException e)
  94.                 {
  95.                 }
  96.         }
  97.         }
  98. }
复制代码

评分

参与人数 1技术分 +2 收起 理由
黄文伯 + 2 赞一个!

查看全部评分

回复 使用道具 举报

谢了,果然是大神也、、、
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马