黑马程序员技术交流社区

标题: 关于多生产者、多消费者 停止程序问题------>求大神指点 [打印本页]

作者: 小歪    时间: 2014-4-20 22:05
标题: 关于多生产者、多消费者 停止程序问题------>求大神指点

关于多生产者、多消费者  停止程序问题




        看完毕老师的多生产者和多消费者后,也写出了代码,但是代码中一直在生产、消费状态,现在如果加入条件使其只生产、消费100个商品后顺利结束程序,有什么好方法,毕老师后面讲的让线程强制启动避免程序挂起,我也想试着加入到多生产、多消费程序中,却不知道从何下手,可能是本人技术不到家,最后听一位朋友建议在生产者和消费者中分别加入了静态(static)的计数器(count)才算解决,可毕竟静态(static)对象是无法在内存中清除的,有没有更好的方法,哪位大神教教我。

具体代码如下:
  1. package ClassPackage;

  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;

  5. /*
  6. 利用JDK1.5新特性 解决   “多生产者、多消费者问题”
  7.          1、实现多个个线程同时生产、多个线程同时消费状态
  8.          2、不能出现共享资源安全问题
  9.          3、不能出现死锁状态
  10.          4、唤醒线程时,只能唤醒对方线程,不可唤醒本方线程
  11.          5、生产、消费100个产品后,程序结束
  12. */

  13. class  Resource{   //共享资源类
  14.         private String obj;   //当前操作资源对象
  15.         private int count=1 ;                //资源
  16.         private boolean flag=false;  
  17.        
  18.         public int getCount()
  19.         {
  20.                 return count;
  21.         }
  22.         //一把锁,两个线程池
  23.         private Lock lock=new ReentrantLock();  
  24.         private  Condition  con_pro=lock.newCondition();
  25.         private  Condition  con_con=lock.newCondition();
  26.        
  27.         public void set(String user)
  28.         {
  29.                
  30.                         lock.lock();
  31.                         try {
  32.                                 while(flag)
  33.                                 {
  34.                                         con_pro.await();
  35.                                 }
  36.                                                 this.obj=user;
  37.                                                 System.out.println(Thread.currentThread().getName()+":"+obj+"---->生产商品"+count);
  38.                                                 flag=true;
  39.                                                 con_con.signal(); //唤醒消费者线程池中第一个线程
  40.                                         } catch (Exception e) {
  41.                                                 e.printStackTrace();
  42.                                                
  43.                                 }finally{
  44.                                         lock.unlock();          //无论是否出现异常    最后必须放开锁
  45.                                 }
  46.                
  47.         }
  48.        
  49.         public void get(String obj)
  50.         {
  51.                
  52.                         lock.lock();
  53.                         try {
  54.                                 while(!flag)
  55.                                 {
  56.                                         con_con.await();
  57.                                 }
  58.                                         System.out.println(Thread.currentThread().getName()+":"+obj+"--------------->消费商品"+count++);
  59.                                         flag=false;
  60.                                         con_pro.signal();//唤醒生产者线程池中第一个线程
  61.                                 } catch (Exception e) {
  62.                                         e.printStackTrace();
  63.                                 }finally{
  64.                                         lock.unlock();                 //无论是否出现异常    最后必须放开锁
  65.                                 }
  66.                 }
  67.         }


  68. class Producer implements Runnable
  69. {
  70.         static int count=0;
  71.         private Resource res;
  72.         public Producer(Resource res)
  73.         {
  74.                 this.res=res;
  75.         }
  76.         public void run() {
  77.                 while(count<100)
  78.                 {
  79.                         count++;
  80.                         res.set("生产者");
  81.                
  82.                 }
  83.                
  84.         }
  85.        
  86. }

  87. class Consumer implements Runnable
  88. {
  89.         static int count=0;
  90.         private Resource res;
  91.         int num=1;
  92.         public Consumer(Resource res)
  93.         {
  94.                 this.res=res;
  95.         }
  96.         public void run() {
  97.                 while(count<100)
  98.                 {
  99.                         count++;
  100.                         res.get("消费者");
  101.                        
  102.                 }
  103.         }
  104.        
  105. }
  106. public class Test30 {
  107.         public static void main(String args[])
  108.         {
  109.                 Resource r=new Resource();
  110.                 Producer pro=new Producer(r);
  111.                 Consumer con=new Consumer(r);
  112.                
  113.                 Thread t1=new Thread(pro);  
  114.                 Thread t2=new Thread(pro);
  115.                 //两个生产者线程、两个消费者线程
  116.                 Thread t3=new Thread(con);
  117.                 Thread t4=new Thread(con);
  118.                
  119.                 t1.start();
  120.                 t2.start();
  121.                 t3.start();
  122.                 t4.start();

  123.         }
  124. }
复制代码

运行后貌似解决了问题,但脑子里还是有点稀里糊涂:






有没有更好的方法,受教了!!!!



作者: 小歪    时间: 2014-4-20 22:08
还有就是  如果将  84行  和  85行 位置换一下,线程就又会挂起,谁帮忙讲解一下?
作者: 小歪    时间: 2014-4-21 08:06
没人知道吗????
作者: osully    时间: 2014-4-21 10:11
让函数自身返回值 改成boolean 类型应该可以尝试一下
你看看下面我改了下还算符合你的要求不
应该算是解决了静态的不?

  1. package NoUseArea;

  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;

  5. /*
  6. 利用JDK1.5新特性 解决   “多生产者、多消费者问题”
  7. 1、实现多个个线程同时生产、多个线程同时消费状态
  8. 2、不能出现共享资源安全问题
  9. 3、不能出现死锁状态
  10. 4、唤醒线程时,只能唤醒对方线程,不可唤醒本方线程
  11. 5、生产、消费100个产品后,程序结束
  12. */

  13. class Resource { // 共享资源类
  14.         private String obj; // 当前操作资源对象
  15.         private int count = 0; // 资源
  16.         private boolean flag = false;

  17.         public int getCount() {
  18.                 return count;
  19.         }

  20.         // 一把锁,两个线程池
  21.         private Lock lock = new ReentrantLock();
  22.         private Condition con_pro = lock.newCondition();
  23.         private Condition con_con = lock.newCondition();

  24.         public boolean set(String user) {
  25.                 lock.lock();
  26.                 try {
  27.                         while (flag) {
  28.                                 con_pro.await();
  29.                         }
  30.                         this.obj = user;
  31.                         if (count < 100) {
  32.                                 System.out.println(Thread.currentThread().getName() + ":" + obj
  33.                                                 + "---->生产商品" + ++count);
  34.                         }
  35.                         flag = true;
  36.                         con_con.signal();
  37.                         if (count < 100)
  38.                                 return true;
  39.                         return false;
  40.                 }
  41.                 catch (Exception e) {
  42.                         e.printStackTrace();

  43.                 }
  44.                 finally {
  45.                         lock.unlock();
  46.                 }
  47.                 return false;
  48.         }

  49.        
  50.         //因为到100的时候所有线程都需要被唤醒,而且100只想被运行一次
  51.         boolean b = true;

  52.         public boolean get(String obj) {
  53.                 lock.lock();
  54.                 try {
  55.                         while (!flag) {
  56.                                 con_con.await();
  57.                         }
  58.                         if (count < 100) {
  59.                                 System.out.println(Thread.currentThread().getName() + ":" + obj
  60.                                                 + "--------------->消费商品" + count);
  61.                         }
  62.                         if (count == 100) {
  63.                                 synchronized (this) {
  64.                                         if (b) {
  65.                                                 System.out.println(Thread.currentThread().getName()
  66.                                                                 + ":" + obj + "--------------->消费商品" + count);
  67.                                                 b = false;
  68.                                                 flag = false;
  69.                                                 con_pro.signal();
  70.                                         }
  71.                                         return false;
  72.                                 }
  73.                         }
  74.                         flag = false;
  75.                         con_pro.signal();
  76.                         return true;
  77.                 }
  78.                 catch (Exception e) {
  79.                         e.printStackTrace();
  80.                 }
  81.                 finally {
  82.                         lock.unlock(); // 无论是否出现异常 最后必须放开锁
  83.                 }
  84.                 return false;
  85.         }
  86. }

  87. class Producer implements Runnable {
  88.         private Resource res;

  89.         public Producer(Resource res) {
  90.                 this.res = res;
  91.         }

  92.         public void run() {
  93.                 boolean b = res.set("生产者");
  94.                 while (b) {
  95.                         b = res.set("生产者");
  96.                 }
  97.         }

  98. }

  99. class Consumer implements Runnable {
  100.         private Resource res;

  101.         public Consumer(Resource res) {
  102.                 this.res = res;
  103.         }

  104.         public void run() {
  105.                 boolean b = res.get("消费者");
  106.                 while (b) {
  107.                         b = res.get("消费者");
  108.                 }
  109.         }

  110. }

  111. public class Test30 {
  112.         public static void main(String args[]) {
  113.                 Resource r = new Resource();
  114.                 Producer pro = new Producer(r);
  115.                 Consumer con = new Consumer(r);

  116.                 Thread t1 = new Thread(pro);
  117.                 Thread t2 = new Thread(pro);
  118.                 // 两个生产者线程、两个消费者线程
  119.                 Thread t3 = new Thread(con);
  120.                 Thread t4 = new Thread(con);

  121.                 t1.start();
  122.                 t2.start();
  123.                 t3.start();
  124.                 t4.start();

  125.         }
  126. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2