java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例
java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例
BlockingQueue很好的解決了多線(xiàn)程中數(shù)據(jù)的傳輸,首先BlockingQueue是一個(gè)接口,它大致有四個(gè)實(shí)現(xiàn)類(lèi),這是一個(gè)很特殊的隊(duì)列,如果BlockQueue是空的,從BlockingQueue取東西的操作將會(huì)被阻斷進(jìn)入等待狀態(tài),直到BlockingQueue進(jìn)了東西才會(huì)被喚醒.同樣,如果BlockingQueue是滿(mǎn)的,任何試圖往里存東西的操作也會(huì)被阻斷進(jìn)入等待狀態(tài),直到BlockingQueue里有空間才會(huì)被喚醒繼續(xù)操作。
BlockingQueue的四個(gè)實(shí)現(xiàn)類(lèi):
1.ArrayBlockingQueue:規(guī)定大小的BlockingQueue,其構(gòu)造函數(shù)必須帶一個(gè)int參數(shù)來(lái)指明其大小.其所含的對(duì)象是以FIFO(先入先出)順序排序的.
2.LinkedBlockingQueue:大小不定的BlockingQueue,若其構(gòu)造函數(shù)帶一個(gè)規(guī)定大小的參數(shù),生成的BlockingQueue有大小限制,若不帶大小參數(shù),所生成的BlockingQueue的大小由Integer.MAX_VALUE來(lái)決定.其所含的對(duì)象是以FIFO(先入先出)順序排序的
3.PriorityBlockingQueue:類(lèi)似于LinkedBlockQueue,但其所含對(duì)象的排序不是FIFO,而是依據(jù)對(duì)象的自然排序順序或者是構(gòu)造函數(shù)的Comparator決定的順序.
4.SynchronousQueue:特殊的BlockingQueue,對(duì)其的操作必須是放和取交替完成的.
BlockingQueue的常用方法:
1)add(anObject):把a(bǔ)nObject加到BlockingQueue里,即如果BlockingQueue可以容納,則返回true,否則報(bào)異常
2)offer(anObject):表示如果可能的話(huà),將anObject加到BlockingQueue里,即如果BlockingQueue可以容納,則返回true,否則返回false.
3)put(anObject):把a(bǔ)nObject加到BlockingQueue里,如果BlockQueue沒(méi)有空間,則調(diào)用此方法的線(xiàn)程被阻斷直到BlockingQueue里面有空間再繼續(xù).
4)poll(time):取走BlockingQueue里排在首位的對(duì)象,若不能立即取出,則可以等time參數(shù)規(guī)定的時(shí)間,取不到時(shí)返回null
5)take():取走BlockingQueue里排在首位的對(duì)象,若BlockingQueue為空,阻斷進(jìn)入等待狀態(tài)直到Blocking有新的對(duì)象被加入為止
例子:
這個(gè)例子主要模擬了生產(chǎn)者和消費(fèi)者之間的工作流程,是一個(gè)簡(jiǎn)單的消費(fèi)者等待生產(chǎn)者生產(chǎn)產(chǎn)品供消費(fèi)者消費(fèi)的場(chǎng)景。
生產(chǎn)者:
package com.gefufeng;
import java.util.concurrent.BlockingQueue;
public class Producter implements Runnable{
private BlockingQueue<String> blockingQueue;
public Producter(BlockingQueue<String> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
try {
blockingQueue.put("我生產(chǎn)的" + Thread.currentThread().getName());
System.out.println("我生產(chǎn)的" + Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("生產(chǎn)失敗");
}
}
}
消費(fèi)者:
package com.gefufeng;
import java.util.concurrent.BlockingQueue;
public class Customer implements Runnable{
private BlockingQueue<String> blockingQueue;
public Customer(BlockingQueue<String> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
for(;;){
try {
String threadName = blockingQueue.take();
System.out.println("取出:" + threadName);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("取出失敗");
}
}
}
}
執(zhí)行類(lèi):
package com.gefufeng;
import java.util.concurrent.ArrayBlockingQueue;
public class Executer {
public static void main(String[] args) {
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<String>(2);
Producter producter = new Producter(arrayBlockingQueue);
Customer cusotmer = new Customer(arrayBlockingQueue);
new Thread(cusotmer).start();
for(;;){
try {
Thread.sleep(2000);
new Thread(producter).start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
首先是消費(fèi)者循環(huán)等待產(chǎn)品,當(dāng)?shù)谝淮窝h(huán)時(shí)執(zhí)行blockingQueue.take(),是拿不出任何產(chǎn)品的,于是進(jìn)入阻塞狀態(tài),兩秒后,生產(chǎn)者生產(chǎn)了一個(gè)產(chǎn)品,于是blockingQueue拿到產(chǎn)品,打印了日志,然后消費(fèi)者執(zhí)行第二次循環(huán),發(fā)現(xiàn)blockingQueue.take()又沒(méi)拿到產(chǎn)品,于是又進(jìn)入阻塞狀態(tài)。。。依次循環(huán)
感謝閱讀,希望能幫助到大家,謝謝大家,對(duì)本站的支持!
相關(guān)文章
MybatisPlus查詢(xún)條件為空字符串或null問(wèn)題及解決
這篇文章主要介紹了MybatisPlus查詢(xún)條件為空字符串或null問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Java項(xiàng)目實(shí)現(xiàn)五子棋小游戲
這篇文章主要為大家詳細(xì)介紹了Java項(xiàng)目實(shí)現(xiàn)五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
關(guān)于Mybatis與JPA的優(yōu)缺點(diǎn)說(shuō)明
這篇文章主要介紹了關(guān)于Mybatis與JPA的優(yōu)缺點(diǎn)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
springboot使用Redis隊(duì)列實(shí)戰(zhàn)
本文主要介紹了springboot使用Redis隊(duì)列實(shí)戰(zhàn),包含四種實(shí)現(xiàn)方式,基于List的 LPUSH+BRPOP的實(shí)現(xiàn), 基于Sorted-Set的實(shí)現(xiàn),PUB/SUB訂閱/發(fā)布模式和基于Stream類(lèi)型的實(shí)現(xiàn),感興趣的可以了解一下2024-07-07
解析spring-security權(quán)限控制和校驗(yàn)的問(wèn)題
這篇文章主要介紹了解析spring-security權(quán)限控制和校驗(yàn)的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Java并發(fā)線(xiàn)程之線(xiàn)程池的知識(shí)總結(jié)
這篇文章主要介紹了Java并發(fā)線(xiàn)程之線(xiàn)程池的知識(shí)總結(jié),幫助大家更好的理解和學(xué)習(xí)Java并發(fā)線(xiàn)程的相關(guān)內(nèi)容,感興趣的朋友可以了解下2021-01-01

