Java多线程(java.util.concurrent.Semaphore)-信号量(Semaphore)在生产者和消费者模式的使用(转载)

 Semaphore 信号量,就是一个允许实现设置好的令牌。也许有1个,也许有10个或更多。 
谁拿到令牌(acquire)就可以去执行了,如果没有令牌则需要等待。 
执行完毕,一定要归还(release)令牌,否则令牌会被很快用光,别的线程就无法获得令牌而执行下去了。

 

请仔细体会里面关于仓库的处理,

1 是如何保证入库时,如果仓库满就等待,

2 出库时,如果仓库无货就等待的。

3 以及对仓库只有10个库位的处理。

4 对同步问题的处理。

  1 /**
  2  * 信号量(Semaphore)的使用。<br>
  3  * 生产者和消费者的例子,库存的管理。
  4  */
  5 public class TestSemaphore {
  6     public static void main(String[] args) {
  7         // 启动线程
  8         for (int i = 0; i <= 3; i++) {
  9             // 消费者
 10             new Thread(new Consumer()).start();
 11             // 生产者
 12             new Thread(new Producer()).start();
 13 
 14         }
 15     }
 16 
 17     // 仓库
 18     static Warehouse buffer = new Warehouse();
 19 
 20     // 生产者,负责增加
 21     static class Producer implements Runnable {
 22         static int num = 1;
 23 
 24         @Override
 25         public void run() {
 26             int n = num++;
 27             while (true) {
 28                 try {
 29                     buffer.put(n);
 30                     System.out.println(">>>" + n);
 31                     // 速度较快。休息10毫秒
 32                     Thread.sleep(10);
 33                 } catch (InterruptedException e) {
 34                     e.printStackTrace();
 35                 }
 36             }
 37         }
 38     }
 39 
 40     // 消费者,负责减少
 41     static class Consumer implements Runnable {
 42         @Override
 43         public void run() {
 44             while (true) {
 45                 try {
 46                     System.out.println("<" + buffer.take());
 47                     // 速度较慢,休息1000毫秒
 48                     Thread.sleep(1000);
 49                 } catch (InterruptedException e) {
 50                     e.printStackTrace();
 51                 }
 52             }
 53         }
 54     }
 55 
 56     /**
 57      * 仓库
 58      *
 59      */
 60     static class Warehouse {
 61         // 非满锁
 62         final Semaphore notFull = new Semaphore(10);
 63         // 非空锁
 64         final Semaphore notEmpty = new Semaphore(0);
 65         // 核心锁
 66         final Semaphore mutex = new Semaphore(1);
 67         // 库存容量
 68         final Object[] items = new Object[10];
 69         int putptr, takeptr, count;
 70 
 71         /**
 72          * 把商品放入仓库.<br>
 73          * 
 74          * @param x
 75          * @throws InterruptedException
 76          */
 77         public void put(Object x) throws InterruptedException {
 78             // 保证非满
 79             notFull.acquire();
 80             // 保证不冲突
 81             mutex.acquire();
 82             try {
 83                 // 增加库存
 84                 items[putptr] = x;
 85                 if (++putptr == items.length)
 86                     putptr = 0;
 87                 ++count;
 88             } finally {
 89                 // 退出核心区
 90                 mutex.release();
 91                 // 增加非空信号量,允许获取商品
 92                 notEmpty.release();
 93             }
 94         }
 95 
 96         /**
 97          * 从仓库获取商品
 98          * 
 99          * @return
100          * @throws InterruptedException
101          */
102         public Object take() throws InterruptedException {
103             // 保证非空
104             notEmpty.acquire();
105             // 核心区
106             mutex.acquire();
107             try {
108                 // 减少库存
109                 Object x = items[takeptr];
110                 if (++takeptr == items.length)
111                     takeptr = 0;
112                 --count;
113                 return x;
114             } finally {
115                 // 退出核心区
116                 mutex.release();
117                 // 增加非满的信号量,允许加入商品
118                 notFull.release();
119             }
120         }
121     }
122 }

原文地址:http://blog.csdn.net/java2000_net/article/details/3997449

posted @ 2013-04-09 17:16  Agrimony  阅读(234)  评论(0)    收藏  举报