ArrayBlockQueue 可阻塞的隊列
> 隊列包含固定長度的隊列和不固定長度的隊列。
> ArrayBlockQueue
> 看BlockingQueue類的幫助文檔,其中有各個方法的區別對比的表格。
> 只有put方法和 take 方法才具有阻塞功能
> 用3個空間的隊列來演示阻塞隊列的功能和效果
/* * 兩個線程向隊列中放數據,一個線程從隊列中取數據 */ public class BlockingQueueTest { public static void main(String[] args) { final BlockingQueue queue = new ArrayBlockingQueue(3); for(int i = 0;i<2;i++){ new Thread(){ public void run() { while(true){ try { Thread.sleep((long)(Math.random()*1000)); System.out.println(Thread.currentThread().getName() +"准備放數據"); queue.put(1); System.out.println(Thread.currentThread().getName() +"隊列目前有"+queue.size()+"個數據"); } catch (Exception e) { e.printStackTrace(); } } }; }.start(); } new Thread(){ public void run() { while(true){ try { //將此處的睡眠時間分別改為100和1000,觀察運行結果 Thread.sleep(1000); System.out.println(Thread.currentThread().getName() +"准備取數據"); queue.take(); System.out.println(Thread.currentThread().getName() +"隊列目前有"+queue.size()+"個數據"); } catch (Exception e) { e.printStackTrace(); } } }; }.start(); } }
>用兩個具有1個空間的隊列來實現同步通知的功能
/** * 改造之前的程序,用兩個具有1個空間的隊列來實現同步通知的功能 * 使用阻塞隊列實現 * 子線程循環10次,接着主線程循環100次,接着又回到子線程循環10次,接着又 主線程循環100次,如此循環50次,請寫出程序 * * @author Administrator * */ public class BlockingQueueCommunication { public static void main(String[] args) { final Business5 business = new Business5(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 50; i++) { business.sub(i); } } }).start(); for (int i = 1; i <= 50; i++) { business.main(i); } } static class Business5 { BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<>(1); BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<>(1); //這種寫法叫 匿名構造方法,運行時機在任何構造方法之前,創建多少個對象就會調用多少次, 而static{} 靜態代碼塊在類加載的時候調用且只調用一次 { try { queue2.put(1); } catch (InterruptedException e) { e.printStackTrace(); } } public void sub(int i) { try { queue1.put(1); } catch (InterruptedException e) { e.printStackTrace(); } for (int j = 1; j <= 100; j++) { System.out.println("sub thread sequence of " + j + ", loop of " + i); } try { queue2.take(); } catch (InterruptedException e) { e.printStackTrace(); } } public void main(int i) { try { queue2.put(1); } catch (InterruptedException e) { e.printStackTrace(); } for (int j = 1; j <= 10; j++) { System.out.println("main thread sequence of " + j + ", loop of " + i); } try { queue1.take(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }