線程隊列之阻塞隊列LinkedBlockingQueue
阿新 • • 發佈:2017-05-31
兩個 trace strong implement thread 提高效率 實際應用 code 執行
在Java多線程應用中,隊列的使用率很高,多數生產消費模型的首選數據結構就是隊列(先進先出)。Java提供的線程安全的Queue可以分為阻塞隊列和非阻塞隊列,其中阻塞隊列的典型例子是BlockingQueue,非阻塞隊列的典型例子是ConcurrentLinkedQueue,在實際應用中要根據實際需要選用阻塞隊列或者非阻塞隊列。
註:什麽叫線程安全?這個首先要明確。線程安全就是說多線程訪問同一代碼,不會產生不確定的結果。
並行和並發區別
1、並行是指兩者同時執行一件事,比如賽跑,兩個人都在不停的往前跑;
2、並發是指資源有限的情況下,兩者交替輪流使用資源,比如一段路(單核CPU資源)同時只能過一個人,A走一段後,讓給B,B用完繼續給A ,交替使用,目的是提高效率
LinkedBlockingQueue
由於LinkedBlockingQueue實現是線程安全的,實現了先進先出等特性,是作為生產者消費者的首選,LinkedBlockingQueue
可以指定容量,也可以不指定,不指定的話,默認最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在隊列滿的時候會阻塞直到有隊列成員被消費,take方法在隊列空的時候會阻塞,直到有隊列成員被放進來。
1 package cn.thread; 2 3 import java.util.concurrent.BlockingQueue; 4 importjava.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.LinkedBlockingQueue; 7 8 /** 9 * 多線程模擬實現生產者/消費者模型 10 */ 11 public class BlockingQueueTest2 { 12 /** 13 * 14 * 定義裝蘋果的籃子 15 * 16 */ 17 public classBasket { 18 // 籃子,能夠容納3個蘋果 19 BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3); 20 21 // 生產蘋果,放入籃子 22 public void produce() throws InterruptedException { 23 // put方法放入一個蘋果,若basket滿了,等到basket有位置 24 basket.put("An apple"); 25 } 26 27 // 消費蘋果,從籃子中取走 28 public String consume() throws InterruptedException { 29 // take方法取出一個蘋果,若basket為空,等到basket有蘋果為止(獲取並移除此隊列的頭部) 30 return basket.take(); 31 } 32 } 33 34 // 定義蘋果生產者 35 class Producer implements Runnable { 36 private String instance; 37 private Basket basket; 38 39 public Producer(String instance, Basket basket) { 40 this.instance = instance; 41 this.basket = basket; 42 } 43 44 public void run() { 45 try { 46 while (true) { 47 // 生產蘋果 48 System.out.println("生產者準備生產蘋果:" + instance); 49 basket.produce(); 50 System.out.println("!生產者生產蘋果完畢:" + instance); 51 // 休眠300ms 52 Thread.sleep(300); 53 } 54 } catch (InterruptedException ex) { 55 System.out.println("Producer Interrupted"); 56 } 57 } 58 } 59 60 // 定義蘋果消費者 61 class Consumer implements Runnable { 62 private String instance; 63 private Basket basket; 64 65 public Consumer(String instance, Basket basket) { 66 this.instance = instance; 67 this.basket = basket; 68 } 69 70 public void run() { 71 try { 72 while (true) { 73 // 消費蘋果 74 System.out.println("消費者準備消費蘋果:" + instance); 75 System.out.println(basket.consume()); 76 System.out.println("!消費者消費蘋果完畢:" + instance); 77 // 休眠1000ms 78 Thread.sleep(1000); 79 } 80 } catch (InterruptedException ex) { 81 System.out.println("Consumer Interrupted"); 82 } 83 } 84 } 85 86 public static void main(String[] args) { 87 BlockingQueueTest2 test = new BlockingQueueTest2(); 88 89 // 建立一個裝蘋果的籃子 90 Basket basket = test.new Basket(); 91 92 ExecutorService service = Executors.newCachedThreadPool(); 93 Producer producer = test.new Producer("生產者001", basket); 94 Producer producer2 = test.new Producer("生產者002", basket); 95 Consumer consumer = test.new Consumer("消費者001", basket); 96 service.submit(producer); 97 service.submit(producer2); 98 service.submit(consumer); 99 // 程序運行5s後,所有任務停止 100 // try { 101 // Thread.sleep(1000 * 5); 102 // } catch (InterruptedException e) { 103 // e.printStackTrace(); 104 // } 105 // service.shutdownNow(); 106 } 107 108 }
線程隊列之阻塞隊列LinkedBlockingQueue