概述
實現我上一篇博客中提到的
實際上,就是用synchronized代碼塊解決線程安全問題,以及利用wait()、notify()實現線程阻塞、喚醒。
實現
pollV3()
private Object lockBySynchronized=new Object();
public int pollV3() {synchronized (lockBySynchronized){ //synchronized代碼塊解決線程安全問題 while (tail == 0) { // 沒有元素try {lockBySynchronized.wait(); // 讓出隊元素的線程阻塞 直到被其他線程喚醒} catch (InterruptedException e) {log.info("等待隊列有元素的過程中被打斷",e);}}int polled = arr[0]; // 隊頭元素log.info("出隊成功,隊頭元素為:{}",polled);System.arraycopy(arr,1,arr,0,tail-1);tail--; // 出隊后 tail往前移動一位lockBySynchronized.notify();return polled;}}
offerV3()
public void offerV3(int value) {synchronized (lockBySynchronized){while (tail == capacity) {try {lockBySynchronized.wait(); // 當前線程阻塞直到被喚醒或打斷(其他線程調用signal方法,并且喚醒的線程剛好是該線程或其他線程調用signalAll方法) 關聯該condition的鎖會被自動釋放} catch (InterruptedException e) {log.info("被打斷了...");}}arr[tail] = value;log.info("元素 {}入隊成功",value);tail++;lockBySynchronized.notify(); // 喚醒要出隊元素的線程 執行出隊元素的邏輯}}
測試用例
public static void main(String[] args) throws InterruptedException {ArrayQueue queue = new ArrayQueue(3);Thread t1 = new Thread(() -> {queue.offerV3(1);queue.offerV3(2);}, "t1");Thread t2 = new Thread(() -> {queue.offerV3(3);}, "t2");Thread t3 = new Thread(() -> {queue.offerV3(4);}, "t3");t1.start();t2.start();t3.start();//25ms以后執行一次出隊操作 由于發生了出隊操作 入隊操作就應該可以成功log.info("5s以后執行一次出隊操作");TimeUnit.SECONDS.sleep(5);int polled = queue.pollV3();log.info("出隊的元素:{}",polled);// t1 t2 t3 3個線程的代碼都執行完后再遍歷隊列t1.join();t2.join();t3.join();queue.print();}
測試用例輸出
最后
這篇博客應該就是基于數組實現隊列的最后一篇了吧。
好了,如果對你有幫助的話,歡迎點個免費的贊哦。