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

浙公网安备 33010602011771号