1. 程式人生 > >生產者-消費者問題 java實現

生產者-消費者問題 java實現

import java.util.concurrent.Semaphore;

/**
 * 訊號量(Semaphore)的使用。 <br>
 * 生產者和消費者的例子,庫存的管理。
 */
public class ProducerAndConsumer {
     public static void main(String[] args) {
            // 啟動執行緒
            for ( int i = 0; i <= 3; i++) {
                 // 生產者
                 new Thread( new Producer()).start();
                 // 消費者
                 new Thread( new Consumer()).start();
           }
     }

     // 倉庫
     static Warehouse buffer = new Warehouse();

     // 生產者,負責增加
     static class Producer implements Runnable {
            static int num = 1;

            @Override
            public void run() {
                 int n = num++;
                 while ( true) {
                      try {
                            buffer.put(n);
                           System. out.println( ">" + n);
                            // 速度較快。休息10毫秒
                           Thread. sleep(10);
                     } catch (InterruptedException e) {
                           e.printStackTrace();
                     }
                }
           }
     }

     // 消費者,負責減少
     static class Consumer implements Runnable {
            @Override
            public void run() {
                 while ( true) {
                      try {
                           System. out.println( "<" + buffer.take());
                            // 速度較慢,休息1000毫秒
                           Thread. sleep(1000);
                     } catch (InterruptedException e) {
                           e.printStackTrace();
                     }
                }
           }
     }

     /**
      * 倉庫
      */
     static class Warehouse {
            // 非滿鎖
            final Semaphore notFull = new Semaphore(10);
            // 非空鎖
            final Semaphore notEmpty = new Semaphore(0);
            // 核心鎖
            final Semaphore mutex = new Semaphore(1);
            // 庫存容量
            final Object[] items = new Object[10];
            int putptr, takeptr, count;

            /**
            * 把商品放入倉庫. <br>
            *
            * @param x
            * @throws InterruptedException
            */
            public void put(Object x) throws InterruptedException {
                 // 保證非滿
                 notFull.acquire();
                 // 保證不衝突
                 mutex.acquire();
                 try {
                      // 增加庫存
                      items[ putptr] = x;
                      if (++ putptr == items. length)
                            putptr = 0;
                     ++ count;
                } finally {
                      // 退出核心區
                      mutex.release();
                      // 增加非空訊號量,允許獲取商品
                      notEmpty.release();
                }
           }

            /**
            * 從倉庫獲取商品
            *
            * @return
            * @throws InterruptedException
            */
            public Object take() throws InterruptedException {
                 // 保證非空
                 notEmpty.acquire();
                 // 核心區
                 mutex.acquire();
                 try {
                      // 減少庫存
                     Object x = items[ takeptr];
                      if (++ takeptr == items. length)
                            takeptr = 0;
                     -- count;
                      return x;
                } finally {
                      // 退出核心區
                      mutex.release();
                      // 增加非滿的訊號量,允許加入商品
                      notFull.release();
                }
           }
     }
}