亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁技術文章
文章詳情頁

Java實現(xiàn)自定義阻塞隊列

瀏覽:46日期:2022-08-22 18:09:39

今天重溫了下 java 多線程中的 notify() 方法以及 wait() 方法,一時興起,決定通過這倆個方法,實現(xiàn)一個簡易的自定義阻塞隊列。

阻塞隊列是什么,與普通隊列的區(qū)別是什么?阻塞隊列與普通隊列的區(qū)別在于,當隊列是空的時,從隊列中獲取元素的操作將會被阻塞,或者當隊列是滿時,往隊列里添加元素的操作會被阻塞。試圖從空的阻塞隊列中獲取元素的線程將會被阻塞,直到其他的線程往空的隊列插入新的元素。同樣,試圖往已滿的阻塞隊列中添加新元素的線程同樣也會被阻塞,直到其他的線程使隊列重新變得空閑起來。

1.新建一個 MyQueue.java 類

import java.util.LinkedList;import java.util.concurrent.atomic.AtomicInteger;import com.xiaoleilu.hutool.util.StrUtil;/** * 使用 notify() 和 wait() 實現(xiàn)自定義阻塞隊列 * * @author Yangkai.Shen * @version 1.0 * @date 2017.08.02 at 11:51:14 */public class MyQueue {// 1. 承載數(shù)據(jù)的容器private LinkedList<Object> queue = new LinkedList<Object>();// 2. 計數(shù)器,用于判定邊界private AtomicInteger count = new AtomicInteger(0);private final int minSize = 0;// 3. 初始化一個對象,用于加鎖private final Object lock = new Object();private final int maxSize;public MyQueue(int maxSize) {this.maxSize = maxSize;}/** * 添加一個元素到隊列中,如果隊列元素已滿,則調用此方法的線程被阻塞,直到存在多余空間了,再進行添加 * * @param obj 添加 obj 到隊列尾部 */public void put(Object obj) {synchronized (lock) {// 1.沒有多余空間,就阻塞線程while (count.get() == this.maxSize) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 2.添加元素queue.add(obj);// 3.計數(shù)器累加count.incrementAndGet();System.out.println(StrUtil.format('新加入的元素為:{}', obj));// 4.喚醒其他線程(若本來元素為空,有線程調用 get 方法,那么原本被阻塞的,需要在此時被喚醒)lock.notify();}}/** * 獲取一個元素,如果隊列元素為空,則調用此方法的線程被阻塞,直到添加新元素了,再進行獲取 * * @return 返回隊列的第一個元素 */public Object get() {Object ret = null;synchronized (lock) {// 1.沒有元素,就阻塞線程while (count.get() == this.minSize) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 2.取第一個元素ret = queue.removeFirst();// 3.計數(shù)器遞減count.decrementAndGet();System.out.println(StrUtil.format('移除的元素為:{}', ret));// 4.喚醒其他線程(若元素本來已滿,有線程調用 put 方法,那么原本被阻塞的,需要在此時被喚醒)lock.notify();}return ret;}public int getSize() {return this.count.get();}}

2.新建一個測試類 MyQueueTest.java,測試類中,我們初始化一個隊列,并將元素填滿,然后啟動一個線程 t1,去插入數(shù)據(jù),中間休眠 2s,再去啟動一個線程 t2 取數(shù)據(jù)。

import com.xiaoleilu.hutool.util.StrUtil;import java.util.concurrent.TimeUnit;public class MyQueueTest {public static void main(String[] args) {final MyQueue queue = new MyQueue(5);queue.put('a');queue.put('b');queue.put('c');queue.put('d');queue.put('e');System.out.println(StrUtil.format('當前隊列的長度: {}', queue.getSize()));Thread t1 = new Thread(() -> {queue.put('f');queue.put('g');queue.put('h');}, 't1'); Thread t2 = new Thread(() -> { queue.get(); queue.get(); }); t1.start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } t2.start();}

3.啟動測試類,查看運行結果??刂婆_如果應該出現(xiàn)的效果是,隊列先初始化完成,然后休眠 2s,接下來先取數(shù)據(jù),再插入數(shù)據(jù),則證明阻塞隊列生效。下面是控制臺運行的效果:

初始化隊列

Java實現(xiàn)自定義阻塞隊列

休眠 2s 后取隊首元素,再插入隊尾元素

Java實現(xiàn)自定義阻塞隊列

此時我們會發(fā)現(xiàn),程序還未停止,因為此時隊列已滿,但是線程 t1 還未插入 h 元素,因此線程被阻塞著,直至下次隊列有空余空間才會被喚醒。

4.至此,一個自定義阻塞隊列就已經(jīng)實現(xiàn)了。

5.細心的朋友會發(fā)現(xiàn),我打印的 log 里用到了一個 StrUtil.format() 方法,這個和 slf4j 的 log 用法一致,可以使用占位符。這個是用到了一個國產(chǎn)良心工具類,hutool,國產(chǎn)開源,需要大家的支持,覺得好用的話,期望可以去 碼云 或者 github 上給個 Star 吧!

以上就是Java實現(xiàn)自定義阻塞隊列的詳細內容,更多關于Java 自定義阻塞隊列的資料請關注好吧啦網(wǎng)其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 日本黄色官网 | 91视频国内 | 久久狠狠一本精品综合网 | 日本加勒比在线观看 | 亚洲片在线观看 | 日韩在线播放中文字幕 | 国产一区二区三区在线观看影院 | 欧美另类老妇 | 韩国v欧美v亚洲v日本v | 亚洲另类激情综合偷自拍 | 午夜影院黄色片 | 欧美一线不卡在线播放 | 综合 欧美 亚洲日本 | 成年大片免费视频播放手机不卡 | 欧美一级成人 | 亚洲精品xxxxx| 久久91av | 免费成年人在线视频 | 福利云 | 一级做a爰片久久毛片看看 一级做a爰片久久毛片鸭王 | 国语精品视频在线观看不卡 | 亚洲男人的天堂网 | 日韩 国产 在线 | 黄频漫画| 在线色网址 | 久久免费精品视频在线观看 | 久久欧美精品欧美九久欧美 | 国产黄毛片 | 久久成人精品 | 国产丶欧美丶日韩丶不卡影视 | 久草在线视频免费播放 | 精品久久久久久国产 | 国产欧美日韩另类 | 免费看国产精品久久久久 | 亚洲网在线观看 | 在线视免费频观看韩国aaa | 欧美日韩视频免费播放 | 毛片特黄 | 国内精品自产拍在线观看91 | 国产性tv国产精品 | 日韩三级视频在线观看 |