有趣的生产者消费者问题

转载请注明出处:http://blog.csdn.net/sunyujia/

论坛上的网友提出的问题,每生产3个只能消费2个,感觉不是很难于是动手操之,为了省事

在原来的http://blog.csdn.net/sunyujia/archive/2008/05/02/2362015.aspx 基础上修改的。

唯一的难点在于生产3个的线程不是同一线程。消费2个的线程不是同一线程。就是说不能是一个线程连续生产3个,一个线程连续消费2个,如果是一个线程连续生产的话,程序就没意思了。

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. /**
  6.  * 有趣的生产者消费者问题
  7.  * 每生成3个消费2个
  8.  * @author: sunyujia
  9.  * @blog: http://blog.csdn.net/sunyujia/
  10.  * @mail: sunyujia@sunyujia@yahoo.cn
  11.  */
  12. public class ExecutorServiceTest {
  13.     private static int produceCount = 0;
  14.     private static int consumeCount = 0;
  15.     private static Object produceLock = new Object();
  16.     private static Object consumeLock = new Object();
  17.     public static void main(String[] args) {
  18.         final List tasks = new ArrayList();
  19.         System.out.println("MyBlog: http://blog.csdn.net/"+"sunyujia/");
  20.         final ExecutorService exec = Executors.newCachedThreadPool();
  21.         for (int i = 0; i < 10; i++) {//10个生产者
  22.             exec.execute(new Runnable() {
  23.                 public void run() {
  24.                     while (!Thread.interrupted()) {
  25.                         try {
  26.                             synchronized (consumeLock) {
  27.                                 if (produceCount >= 3)
  28.                                     consumeLock.wait();
  29.                             }
  30.                             synchronized (produceLock) {
  31.                                 if (produceCount < 3) {
  32.                                     tasks.add(new Object());// 生产
  33.                                     System.out.println(Thread.currentThread().getName()+"生产任务 还剩:" + tasks.size());
  34.                                     produceCount++;
  35.                                     if (produceCount >= 3) {
  36.                                         consumeCount = 2;// 提示只能消费2个
  37.                                         System.out.println("生产者友情提示现在库存"
  38.                                                 + tasks.size());
  39.                                         produceLock.notifyAll();
  40.                                     }
  41.                                     Thread.yield();
  42.                                 }
  43.                             }
  44.                             Thread.sleep(600);// 让程序执行慢点以便观察
  45.                         } catch (InterruptedException e) {
  46.                             e.printStackTrace();
  47.                         }
  48.                     }
  49.                 }
  50.             });
  51.         }
  52.         for (int i = 0; i < 20; i++) {//20个消费者
  53.             exec.execute(new Runnable() {
  54.                 public void run() {
  55.                     while (!Thread.interrupted()) {
  56.                         try {
  57.                             synchronized (produceLock) {
  58.                                 if (consumeCount <= 0)
  59.                                     produceLock.wait();
  60.                             }
  61.                             synchronized (consumeLock) {
  62.                                 if (consumeCount > 0) {
  63.                                     tasks.remove(0);// 消费
  64.                                     System.out.println(Thread.currentThread().getName()+"处理任务 还剩:"
  65.                                             + tasks.size());
  66.                                     consumeCount--;
  67.                                     if (consumeCount <= 0) {
  68.                                         produceCount = 0;// 要求再生成3个
  69.                                         System.out.println("消费者友情提示现在库存"
  70.                                                 + tasks.size());
  71.                                         consumeLock.notifyAll();
  72.                                     }
  73.                                 }
  74.                             }
  75.                             Thread.sleep(600);// 让程序执行慢点以便观察
  76.                         } catch (InterruptedException e) {
  77.                             e.printStackTrace();
  78.                         }
  79.                     }
  80.                 }
  81.             });
  82.         }
  83.         exec.shutdown();
  84.     }
  85. }

执行结果如下:
pool-1-thread-1生产任务 还剩:1
pool-1-thread-2生产任务 还剩:2
pool-1-thread-4生产任务 还剩:3
生产者友情提示现在库存3
pool-1-thread-11处理任务 还剩:2
pool-1-thread-12处理任务 还剩:1
消费者友情提示现在库存1
pool-1-thread-5生产任务 还剩:2
pool-1-thread-6生产任务 还剩:3
pool-1-thread-7生产任务 还剩:4
生产者友情提示现在库存4
pool-1-thread-14处理任务 还剩:3
pool-1-thread-16处理任务 还剩:2
消费者友情提示现在库存2
pool-1-thread-3生产任务 还剩:3
pool-1-thread-2生产任务 还剩:4
pool-1-thread-4生产任务 还剩:5
生产者友情提示现在库存5

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值