前面那篇文章我们用wait和notify实现了生产者消费者模式,这篇文章我们用await和signalAll实现消费者模式,下面直接贴代码:
1 package com.fanjf.thread; 2 3 import java.util.LinkedList; 4 import java.util.Random; 5 import java.util.concurrent.locks.Condition; 6 import java.util.concurrent.locks.ReentrantLock; 7 8 public class Mycontainer5 { 9 LinkedList<String> list = new LinkedList<>(); 10 final int MAX = 100; 11 ReentrantLock lock = new ReentrantLock(); 12 Condition producer = lock.newCondition(); 13 Condition consumer = lock.newCondition(); 14 private void put(String s){ 15 lock.lock(); 16 while(list.size()==MAX){ 17 try { 18 producer.await(); 19 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 24 } 25 try{ 26 list.add(s); 27 consumer.signalAll(); 28 }finally{ 29 lock.unlock(); 30 } 31 32 33 } 34 private String get(){ 35 lock.lock(); 36 String s = null; 37 while(list.size()==0){ 38 try { 39 consumer.await(); 40 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 } 45 try{ 46 s = list.removeFirst(); 47 producer.signalAll(); 48 }finally{ 49 lock.unlock(); 50 } 51 52 return s; 53 } 54 public static void main(String[] args) { 55 final Mycontainer5 mycontainer5 = new Mycontainer5(); 56 for(int i = 0;i<10;i++){ 57 new Thread(new Runnable() { 58 public void run() { 59 for(int j = 0;j<10;j++){ 60 System.out.println("消费者线程"+Thread.currentThread().getName()+"取出"+mycontainer5.get()); 61 } 62 63 } 64 },"c"+i).start(); 65 } 66 67 for(int i = 0;i<10;i++){ 68 new Thread(new Runnable() { 69 public void run() { 70 for(int j = 0;j<10;j++){ 71 Random random = new Random(); 72 int r = random.nextInt(10); 73 System.out.println("生产者线程"+Thread.currentThread().getName()+"放入"+Integer.toString(r)); 74 mycontainer5.put(Integer.toString(r)); 75 76 } 77 78 } 79 },"p"+i).start(); 80 } 81 82 } 83 }
执行结果如下:
1 生产者线程p0放入5 2 生产者线程p4放入5 3 生产者线程p5放入7 4 生产者线程p3放入4 5 生产者线程p2放入8 6 生产者线程p4放入8 7 生产者线程p1放入8 8 生产者线程p8放入0 9 消费者线程c9取出8 10 消费者线程c6取出5 11 生产者线程p4放入8 12 消费者线程c4取出8 13 消费者线程c5取出4 14 消费者线程c0取出5 15 生产者线程p2放入2 16 生产者线程p2放入4 17 生产者线程p2放入7 18 消费者线程c4取出4 19 消费者线程c4取出7 20 生产者线程p5放入7 21 生产者线程p5放入6 22 生产者线程p0放入8 23 生产者线程p3放入4 24 消费者线程c3取出8 25 生产者线程p7放入4 26 生产者线程p7放入0 27 生产者线程p6放入5 28 消费者线程c4取出4 29 消费者线程c4取出5 30 生产者线程p7放入0 31 生产者线程p7放入2 32 生产者线程p3放入8 33 生产者线程p3放入9 34 消费者线程c5取出4 35 消费者线程c5取出2 36 生产者线程p0放入3 37 生产者线程p0放入6 38 消费者线程c6取出6 39 消费者线程c6取出9 40 生产者线程p5放入1 41 生产者线程p5放入0 42 生产者线程p5放入3 43 生产者线程p5放入3 44 生产者线程p5放入8 45 消费者线程c0取出7 46 消费者线程c0取出6 47 消费者线程c0取出1 48 生产者线程p2放入4 49 生产者线程p2放入8 50 消费者线程c2取出2 51 生产者线程p4放入9 52 生产者线程p4放入5 53 消费者线程c1取出0 54 消费者线程c9取出8 55 生产者线程p8放入9 56 生产者线程p8放入4 57 消费者线程c8取出8 58 消费者线程c8取出4 59 生产者线程p1放入6 60 生产者线程p1放入7 61 生产者线程p9放入9 62 生产者线程p9放入5 63 消费者线程c7取出7 64 消费者线程c7取出9 65 消费者线程c7取出5 66 消费者线程c7取出9 67 消费者线程c7取出4 68 生产者线程p9放入9 69 生产者线程p9放入0 70 生产者线程p1放入5 71 生产者线程p1放入0 72 消费者线程c8取出8 73 消费者线程c8取出7 74 生产者线程p8放入1 75 生产者线程p8放入1 76 消费者线程c9取出8 77 消费者线程c9取出5 78 消费者线程c9取出9 79 消费者线程c9取出0 80 消费者线程c9取出5 81 消费者线程c1取出3 82 消费者线程c1取出1 83 消费者线程c1取出1 84 生产者线程p4放入6 85 生产者线程p4放入9 86 消费者线程c2取出3 87 生产者线程p2放入3 88 生产者线程p2放入0 89 消费者线程c0取出0 90 消费者线程c0取出3 91 生产者线程p5放入5 92 生产者线程p5放入5 93 消费者线程c6取出3 94 消费者线程c6取出5 95 消费者线程c6取出5 96 生产者线程p0放入2 97 消费者线程c5取出8 98 生产者线程p3放入1 99 消费者线程c4取出0 100 生产者线程p7放入5 101 生产者线程p6放入0 102 消费者线程c3取出0 103 消费者线程c3取出0 104 生产者线程p6放入1 105 生产者线程p6放入0 106 生产者线程p7放入0 107 生产者线程p7放入2 108 消费者线程c4取出5 109 消费者线程c5取出1 110 生产者线程p3放入7 111 消费者线程c6取出2 112 生产者线程p0放入0 113 消费者线程c0取出0 114 生产者线程p2放入9 115 消费者线程c2取出9 116 消费者线程c2取出0 117 消费者线程c1取出6 118 生产者线程p4放入5 119 生产者线程p4放入1 120 消费者线程c9取出0 121 生产者线程p8放入5 122 生产者线程p8放入9 123 生产者线程p8放入8 124 生产者线程p8放入3 125 生产者线程p8放入2 126 消费者线程c8取出9 127 生产者线程p1放入7 128 生产者线程p9放入2 129 消费者线程c7取出6 130 生产者线程p9放入3 131 生产者线程p1放入3 132 消费者线程c8取出5 133 消费者线程c9取出1 134 消费者线程c9取出3 135 生产者线程p4放入3 136 消费者线程c1取出5 137 消费者线程c2取出9 138 生产者线程p2放入3 139 消费者线程c0取出7 140 生产者线程p0放入4 141 消费者线程c6取出2 142 消费者线程c6取出3 143 生产者线程p3放入5 144 消费者线程c5取出0 145 消费者线程c4取出0 146 消费者线程c4取出3 147 消费者线程c4取出4 148 生产者线程p7放入7 149 生产者线程p6放入9 150 生产者线程p6放入9 151 消费者线程c3取出1 152 生产者线程p6放入5 153 生产者线程p6放入9 154 生产者线程p7放入5 155 生产者线程p7放入5 156 消费者线程c5取出3 157 消费者线程c5取出7 158 消费者线程c5取出9 159 消费者线程c5取出9 160 生产者线程p3放入7 161 消费者线程c6取出3 162 生产者线程p0放入3 163 消费者线程c0取出2 164 消费者线程c0取出5 165 消费者线程c2取出7 166 消费者线程c1取出2 167 消费者线程c1取出5 168 消费者线程c8取出8 169 消费者线程c8取出7 170 生产者线程p1放入9 171 生产者线程p1放入0 172 生产者线程p9放入9 173 消费者线程c7取出9 174 生产者线程p9放入0 175 生产者线程p9放入7 176 生产者线程p1放入4 177 消费者线程c8取出3 178 消费者线程c1取出5 179 消费者线程c1取出9 180 消费者线程c2取出9 181 消费者线程c2取出0 182 消费者线程c2取出7 183 生产者线程p0放入2 184 生产者线程p0放入8 185 生产者线程p3放入1 186 生产者线程p3放入8 187 生产者线程p6放入1 188 消费者线程c3取出5 189 消费者线程c3取出2 190 消费者线程c3取出8 191 消费者线程c3取出1 192 消费者线程c3取出8 193 生产者线程p6放入5 194 消费者线程c2取出4 195 消费者线程c8取出0 196 生产者线程p9放入0 197 消费者线程c7取出9 198 消费者线程c3取出1 199 消费者线程c7取出5 200 消费者线程c7取出0
从上面代码可以看出,await和signalAll实现的生产者消费者模式和用wait和notify实现方式基本相同,不同的一点是用wait和signalAll方式可以精确指定生产者或消费者等待或唤醒,程序的可读性更强,更容易理解。