這篇部落格算是上一篇JAVA多線程(三)生產者消費者模式及實現方法的補充。用三種方法(lock、synchronized、阻塞隊列)實現生產者消費者模式。具體內容是:生產者產生隨機數(為了方便閱讀結果,我把隨機數限定在10以內的整數),消費者讀取並列印。 1 阻塞隊列實現生產者消費者模式
阻塞隊列是最簡單的實現方法
import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.logging.Level;import java.util.logging.Logger;import java.util.Random;public class BlockingQueuePattern { public static void main(String args[]){ //阻塞隊列 BlockingQueue sharedQueue = new LinkedBlockingQueue(); //建立生產者線程和消費者線程 Thread prodThread = new Thread(new Producer(sharedQueue)); Thread consThread = new Thread(new Consumer(sharedQueue)); //啟動生產者線程和消費者線程 prodThread.start(); consThread.start(); }}//生產者類class Producer implements Runnable { private final BlockingQueue sharedQueue; public Producer(BlockingQueue sharedQueue) { this.sharedQueue = sharedQueue; } @Override public void run() { for(int i=0; i<10; i++){ try { //產生10以內的隨機整數放入阻塞隊列 Random random = new Random(); int ProdRandom=random.nextInt(10); System.out.println("Produced: " + ProdRandom); sharedQueue.put(ProdRandom); } catch (InterruptedException ex) { Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex); } } }}//消費者類class Consumer implements Runnable{ private final BlockingQueue sharedQueue; public Consumer (BlockingQueue sharedQueue) { this.sharedQueue = sharedQueue; } @Override public void run() { while(true){ try { System.out.println("Consumed: "+ sharedQueue.take()); } catch (InterruptedException ex) { Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex); } } }} Output:Produced: 4Produced: 7Produced: 8Consumed: 4Consumed: 7Produced: 6Consumed: 8Consumed: 6Produced: 1Produced: 7Consumed: 1Consumed: 7Produced: 3Produced: 5Consumed: 3Consumed: 5Produced: 9Produced: 7Consumed: 9Consumed: 7
2 lock實現生產者消費者模式
既然不用JAVA提供給我們的現成的阻塞隊列,我們不如自己建立一個隊列,代碼如下:
import java.util.LinkedList;import java.util.Random;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class OptimisticLockPattern { public static void main(String[] args){ SelfQueue selfqueue = new SelfQueue(); //建立生產者線程和消費者線程 Thread prodThread = new Thread(new Producer(selfqueue)); Thread consThread = new Thread(new Consumer(selfqueue)); //啟動生產者線程和消費者線程 prodThread.start(); consThread.start(); }}class SelfQueue{ int max = 5; LinkedList<Integer> ProdLine = new LinkedList<Integer>(); Lock lock = new ReentrantLock(); Condition full = lock.newCondition(); Condition empty = lock.newCondition(); public void produce(int ProdRandom){ try { lock.lock(); while(max == ProdLine.size()){ System.out.println("儲存量達到上限,請等待"); full.await(); } ProdLine.add(ProdRandom); empty.signal(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } public int consume(){ int m = 0; try { lock.lock(); while(ProdLine.size() == 0){ System.out.println("隊列是空的,請稍候"); empty.await(); } m = ProdLine.removeFirst(); full.signal(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); return m; } }}//生產者class Producer implements Runnable{ private final SelfQueue selfqueue; public Producer(SelfQueue selfqueue) { this.selfqueue = selfqueue; } public void run() { for (int i = 0; i < 10; i++) { Random random = new Random(); int ProdRandom=random.nextInt(10); System.out.println("Produced: " + ProdRandom); selfqueue.produce(ProdRandom); } }}//消費者class Consumer implements Runnable{ private final SelfQueue selfqueue; public Consumer(SelfQueue selfqueue) { this.selfqueue = selfqueue; } public void run() { while(true) { System.out.println("Consumed: "+ selfqueue.consume()); } }}Output:Produced: 1Produced: 9Consumed: 1Consumed: 9隊列是空的,請稍候Produced: 9Produced: 1Consumed: 9Produced: 8Consumed: 1Consumed: 8隊列是空的,請稍候Produced: 6Produced: 8Consumed: 6Produced: 4Consumed: 8Produced: 4Consumed: 4Produced: 0Consumed: 4Consumed: 0隊列是空的,請稍候
3 synchronized實現生產者消費者模式
synchronized不需要自己手動解鎖,這裡用到了前面提過的wait()¬ify()方法。
import java.util.Random;public class PessimisticLockPattern { public static void main(String[] args){ SelfQueue selfqueue = new SelfQueue(); //建立生產者線程和消費者線程 Thread prodThread = new Thread(new Producer(selfqueue)); Thread consThread = new Thread(new Consumer(selfqueue)); //啟動生產者線程和消費者線程 prodThread.start(); consThread.start(); }}class SelfQueue{ int index = 0; int[] ProdLine = new int[6]; public synchronized void produce(int ProdRandom){ while(index == ProdLine.length){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); ProdLine[index] = ProdRandom; index++; } public synchronized int consume(){ while(index == 0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notify(); index--; return ProdLine[index]; }}//生產者class Producer implements Runnable{ private final SelfQueue selfqueue; public Producer(SelfQueue selfqueue) { this.selfqueue = selfqueue; } public void run() { for (int i = 0; i < 10; i++) { Random random = new Random(); int ProdRandom = random.nextInt(10); System.out.println("Produced: " + ProdRandom); selfqueue.produce(ProdRandom); }}}//消費者class Consumer implements Runnable{ private final SelfQueue selfqueue; public Consumer(SelfQueue selfqueue) { this.selfqueue = selfqueue; } public void run() { while(true) { System.out.println("Consumed: "+ selfqueue.consume()); }}}Output:Produced: 3Produced: 3Consumed: 3Produced: 8Produced: 3Consumed: 3Produced: 2Produced: 6Consumed: 3Produced: 7Produced: 8Produced: 1Produced: 9Consumed: 6Consumed: 9Consumed: 1Consumed: 8Consumed: 7Consumed: 2Consumed: 8