有趣的生產者消費者問題

來源:互聯網
上載者:User

轉載請註明出處: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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.