电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

淺談Java中的Queue家族

瀏覽:115日期:2022-08-11 14:00:57
目錄Queue接口Queue的分類BlockingQueueDequeTransferQueueQueue接口

先看下Queue的繼承關系和其中定義的方法:

淺談Java中的Queue家族

Queue繼承自Collection,Collection繼承自Iterable。

Queue有三類主要的方法,我們用個表格來看一下他們的區別:

方法類型 方法名稱 方法名稱 區別 Insert add offer 兩個方法都表示向Queue中添加某個元素,不同之處在于添加失敗的情況,add只會返回true,如果添加失敗,會拋出異常。offer在添加失敗的時候會返回false。所以對那些有固定長度的Queue,優先使用offer方法。 Remove remove poll 如果Queue是空的情況下,remove會拋出異常,而poll會返回null。 Examine element peek 獲取Queue頭部的元素,但不從Queue中刪除。兩者的區別還是在于Queue為空的情況下,element會拋出異常,而peek返回null。

注意,因為對poll和peek來說null是有特殊含義的,所以一般來說Queue中禁止插入null,但是在實現中還是有一些類允許插入null比如LinkedList。

盡管如此,我們在使用中還是要避免插入null元素。

Queue的分類

一般來說Queue可以分為BlockingQueue,Deque和TransferQueue三種。

BlockingQueue

BlockingQueue是Queue的一種實現,它提供了兩種額外的功能:

當當前Queue是空的時候,從BlockingQueue中獲取元素的操作會被阻塞。當當前Queue達到最大容量的時候,插入BlockingQueue的操作會被阻塞。

BlockingQueue的操作可以分為下面四類:

操作類型Throws exceptionSpecial valueBlocksTimes outInsertadd(e)offer(e)put(e)offer(e, time, unit)Removeremove()poll()take()poll(time, unit)Examineelement()peek()not applicablenot applicable

第一類是會拋出異常的操作,當遇到插入失敗,隊列為空的時候拋出異常。

第二類是不會拋出異常的操作。

第三類是會Block的操作。當Queue為空或者達到最大容量的時候。

第四類是time out的操作,在給定的時間里會Block,超時會直接返回。

BlockingQueue是線程安全的Queue,可以在生產者消費者模式的多線程中使用,如下所示:

class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... } } class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } }

最后,在一個線程中向BlockQueue中插入元素之前的操作happens-before另外一個線程中從BlockQueue中刪除或者獲取的操作。

Deque

Deque是Queue的子類,它代表double ended queue,也就是說可以從Queue的頭部或者尾部插入和刪除元素。

同樣的,我們也可以將Deque的方法用下面的表格來表示,Deque的方法可以分為對頭部的操作和對尾部的操作:

方法類型 Throws exception Special value Throws exception Special value Insert addFirst(e) offerFirst(e) addLast(e) offerLast(e) Remove removeFirst() pollFirst() removeLast() pollLast() Examine getFirst() peekFirst() getLast() peekLast()

和Queue的方法描述基本一致,這里就不多講了。

當Deque以 FIFO (First-In-First-Out)的方法處理元素的時候,Deque就相當于一個Queue。

當Deque以LIFO (Last-In-First-Out)的方式處理元素的時候,Deque就相當于一個Stack。

TransferQueue

TransferQueue繼承自BlockingQueue,為什么叫Transfer呢?因為TransferQueue提供了一個transfer的方法,生產者可以調用這個transfer方法,從而等待消費者調用take或者poll方法從Queue中拿取數據。

還提供了非阻塞和timeout版本的tryTransfer方法以供使用。

我們舉個TransferQueue實現的生產者消費者的問題。

先定義一個生產者:

@Slf4j@Data@AllArgsConstructorclass Producer implements Runnable { private TransferQueue<String> transferQueue; private String name; private Integer messageCount; public static final AtomicInteger messageProduced = new AtomicInteger(); @Override public void run() {for (int i = 0; i < messageCount; i++) { try {boolean added = transferQueue.tryTransfer( '第'+i+'個', 2000, TimeUnit.MILLISECONDS);log.info('transfered {} 是否成功: {}','第'+i+'個',added);if(added){ messageProduced.incrementAndGet();} } catch (InterruptedException e) {log.error(e.getMessage(),e); }}log.info('total transfered {}',messageProduced.get()); }}

在生產者的run方法中,我們調用了tryTransfer方法,等待2秒鐘,如果沒成功則直接返回。

再定義一個消費者:

@Slf4j@Data@AllArgsConstructorpublic class Consumer implements Runnable { private TransferQueue<String> transferQueue; private String name; private int messageCount; public static final AtomicInteger messageConsumed = new AtomicInteger(); @Override public void run() {for (int i = 0; i < messageCount; i++) { try {String element = transferQueue.take();log.info('take {}',element );messageConsumed.incrementAndGet();Thread.sleep(500); } catch (InterruptedException e) {log.error(e.getMessage(),e); }}log.info('total consumed {}',messageConsumed.get()); }}

在run方法中,調用了transferQueue.take方法來取消息。

下面先看一下一個生產者,零個消費者的情況:

@Testpublic void testOneProduceZeroConsumer() throws InterruptedException { TransferQueue<String> transferQueue = new LinkedTransferQueue<>(); ExecutorService exService = Executors.newFixedThreadPool(10); Producer producer = new Producer(transferQueue, 'ProducerOne', 5); exService.execute(producer); exService.awaitTermination(50000, TimeUnit.MILLISECONDS); exService.shutdown();}

輸出結果:

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第0個 是否成功: false

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第1個 是否成功: false

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第2個 是否成功: false

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第3個 是否成功: false

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第4個 是否成功: false

[pool-1-thread-1] INFO com.flydean.Producer - total transfered 0

可以看到,因為沒有消費者,所以消息并沒有發送成功。

再看下一個有消費者的情況:

@Testpublic void testOneProduceOneConsumer() throws InterruptedException { TransferQueue<String> transferQueue = new LinkedTransferQueue<>(); ExecutorService exService = Executors.newFixedThreadPool(10); Producer producer = new Producer(transferQueue, 'ProducerOne', 2); Consumer consumer = new Consumer(transferQueue, 'ConsumerOne', 2); exService.execute(producer); exService.execute(consumer); exService.awaitTermination(50000, TimeUnit.MILLISECONDS); exService.shutdown();}

輸出結果:

[pool-1-thread-2] INFO com.flydean.Consumer - take 第0個

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第0個 是否成功: true

[pool-1-thread-2] INFO com.flydean.Consumer - take 第1個

[pool-1-thread-1] INFO com.flydean.Producer - transfered 第1個 是否成功: true

[pool-1-thread-1] INFO com.flydean.Producer - total transfered 2

[pool-1-thread-2] INFO com.flydean.Consumer - total consumed 2

可以看到Producer和Consumer是一個一個來生產和消費的。

以上就是淺談Java中的Queue家族的詳細內容,更多關于Java中的Queue家族的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 昆明化妆培训-纹绣美甲-美容美牙培训-昆明博澜培训学校 | 罗茨真空机组,立式无油往复真空泵,2BV水环真空泵-力侨真空科技 | 老城街小面官网_正宗重庆小面加盟技术培训_特色面馆加盟|牛肉拉面|招商加盟代理费用多少钱 | 托盘租赁_塑料托盘租赁_托盘出租_栈板出租_青岛托盘租赁-优胜必达 | 民用音响-拉杆音响-家用音响-ktv专用音响-万昌科技 | DAIKIN电磁阀-意大利ATOS电磁阀-上海乾拓贸易有限公司 | 深圳彩钢板_彩钢瓦_岩棉板_夹芯板_防火复合彩钢板_长鑫 | 光照全温振荡器(智能型)-恒隆仪器| 北京翻译公司_同传翻译_字幕翻译_合同翻译_英语陪同翻译_影视翻译_翻译盖章-译铭信息 | 打造全球沸石生态圈 - 国投盛世 锂电混合机-新能源混合机-正极材料混料机-高镍,三元材料混料机-负极,包覆混合机-贝尔专业混合混料搅拌机械系统设备厂家 | 手机存放柜,超市储物柜,电子储物柜,自动寄存柜,行李寄存柜,自动存包柜,条码存包柜-上海天琪实业有限公司 | 粉碎机_塑料粉碎机_塑料破碎机厂家-星标机械 | Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 液压升降货梯_导轨式升降货梯厂家_升降货梯厂家-河南东圣升降设备有限公司 | 捆扎机_气动捆扎机_钢带捆扎机-沈阳海鹞气动钢带捆扎机公司 | led冷热冲击试验箱_LED高低温冲击试验箱_老化试验箱-爱佩百科 | 石英陶瓷,石英坩埚,二氧化硅陶瓷-淄博百特高新材料有限公司 | 冷油器-冷油器换管改造-连云港灵动列管式冷油器生产厂家 | 口臭的治疗方法,口臭怎么办,怎么除口臭,口臭的原因-口臭治疗网 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 浇注料-高铝砖耐火砖-郑州凯瑞得窑炉耐火材料有限公司 | 碎石机设备-欧版反击破-欧版颚式破碎机(站)厂家_山东奥凯诺机械 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 仿古瓦,仿古金属瓦,铝瓦,铜瓦,铝合金瓦-西安东申景观艺术工程有限公司 | 深圳富泰鑫五金_五金冲压件加工_五金配件加工_精密零件加工厂 | PVC快速门-硬质快速门-洁净室快速门品牌厂家-苏州西朗门业 | 沈阳真空机_沈阳真空包装机_沈阳大米真空包装机-沈阳海鹞真空包装机械有限公司 | 爆炸冲击传感器-无线遥测传感器-航天星百科 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 成都中天自动化控制技术有限公司 | 恒温恒湿箱(药品/保健品/食品/半导体/细菌)-兰贝石(北京)科技有限公司 | 齿轮减速马达一体式_蜗轮蜗杆减速机配电机-德国BOSERL齿轮减速电动机生产厂家 | 水篦子|雨篦子|镀锌格栅雨水篦子|不锈钢排水篦子|地下车库水箅子—安平县云航丝网制品厂 | 天津力值检测-天津管道检测-天津天诚工程检测技术有限公司 | 济南网站建设_济南网站制作_济南网站设计_济南网站建设公司_富库网络旗下模易宝_模板建站 | 真空干燥烘箱_鼓风干燥箱 _高低温恒温恒湿试验箱_光照二氧化碳恒温培养箱-上海航佩仪器 | CPSE安博会| 机器视觉检测系统-视觉检测系统-机器视觉系统-ccd检测系统-视觉控制器-视控一体机 -海克易邦 | 纯化水设备-纯水设备-超纯水设备-[大鹏水处理]纯水设备一站式服务商-东莞市大鹏水处理科技有限公司 | 重庆磨床过滤机,重庆纸带过滤机,机床伸缩钣金,重庆机床钣金护罩-重庆达鸿兴精密机械制造有限公司 | 内窥镜-工业内窥镜厂家【上海修远仪器仪表有限公司】 | 定量包装机,颗粒定量包装机,粉剂定量包装机,背封颗粒包装机,定量灌装机-上海铸衡电子科技有限公司 |