日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

java中并發Queue種類與各自API特點以及使用場景說明

瀏覽:189日期:2022-08-11 09:32:46
一 先說下隊列

隊列是一種數據結構.它有兩個基本操作:在隊列尾部加入一個元素,和從隊列頭部移除一個元素(注意不要弄混隊列的頭部和尾部)

就是說,隊列以一種先進先出的方式管理數據,如果你試圖向一個 已經滿了的阻塞隊列中添加一個元素或者是從一個空的阻塞隊列中移除一個元索,將導致線程阻塞.

在多線程進行合作時,阻塞隊列是很有用的工具。工作者線程可以定期地把中間結果存到阻塞隊列中而其他工作者線程把中間結果取出并在將來修改它們。隊列會自動平衡負載。

如果第一個線程集運行得比第二個慢,則第二個 線程集在等待結果時就會阻塞。如果第一個線程集運行得快,那么它將等待第二個線程集趕上來.

說白了,就是先進先出,線程安全!

java中并發隊列都是在java.util.concurrent并發包下的,Queue接口與List、Set同一級別,都是繼承了Collection接口,最近學習了java中的并發Queue的所有子類應用場景,這里記錄分享一下:

1.1 這里可以先用wait與notify(腦忒fai) 模擬一下隊列的增刪數據,簡單了解一下隊列:

import java.util.LinkedList;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;/** * 模擬隊列增刪數據 * @author houzheng */public class MyQueue { //元素集合 private LinkedList<Object> list=new LinkedList<Object>(); //計數器(同步),判斷集合元素數量 private AtomicInteger count=new AtomicInteger(); //集合上限與下限,final必須指定初值 private final int minSize=0; private final int maxSize; //構造器指定最大值 public MyQueue(int maxSize) {this.maxSize = maxSize; } //初始化對象,用于加鎖,也可直接用this private Object lock=new Object(); //put方法:往集合中添加元素,如果集合元素已滿,則此線程阻塞,直到有空間再繼續 public void put(Object obj){synchronized (lock) { while(count.get()==this.maxSize){try { lock.wait();} catch (InterruptedException e) { e.printStackTrace();} } list.add(obj); //計數器加一 count.incrementAndGet(); System.out.println('放入元素:'+obj); //喚醒另一個線程,(處理極端情況:集合一開始就是空,此時take線程會一直等待) lock.notify();} } //take方法:從元素中取數據,如果集合為空,則線程阻塞,直到集合不為空再繼續 public Object take(){Object result=null;synchronized(lock){ while(count.get()==this.minSize){try { lock.wait();} catch (InterruptedException e) { e.printStackTrace();} } //移除第一個 result=list.removeFirst(); //計數器減一 count.decrementAndGet(); System.out.println('拿走元素:'+result); //喚醒另一個線程,(處理極端情況:集合一開始就是滿的,此時put線程會一直等待) lock.notify();}return result; } public int getSize(){return this.count.get(); } public static void main(String[] args) {//創建集合容器MyQueue queue=new MyQueue(5);queue.put('1');queue.put('2');queue.put('3');queue.put('4');queue.put('5');System.out.println('當前容器長度為:'+queue.getSize());Thread t1=new Thread(()->{ queue.put('6'); queue.put('7');},'t1');Thread t2=new Thread(()->{ Object take1 = queue.take(); Object take2 = queue.take();},'t2');//測試極端情況,兩秒鐘后再執行另一個線程t1.start();try { TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) { e.printStackTrace();}t2.start(); }}

這里用線程通信的方式簡單模擬了隊列的進出,那么接下來就正式進入java的并發隊列:

二 并發Queue

JDK中并發隊列提供了兩種實現,一種是高性能隊列ConcurrentLinkedQueue,一種是阻塞隊列BlockingQueue,兩種都繼承自Queue:

1ConcurrentLinkedQueue

這是一個使用于高并發場景的隊列(額,各位看這塊博客的小朋友,最好對線程基礎比較熟悉再來看,當然我也在拼命學習啦,哈哈哈),主要是無鎖的方式,他的想能要比BlockingQueue好

是基于鏈接節點的無界線程安全隊列,先進先出,不允許有null元素,廢話不多說,上demo:

java中并發Queue種類與各自API特點以及使用場景說明

這種queue比較簡單,沒什么好說的,和ArrayList一樣用就可以,關鍵是BlockingQUeue

2BlockingQueue

blockingQueue主要有5中實現,我感覺都挺有意思的,其中幾種還比較常用就都學習了下,這里都介紹下:

java中并發Queue種類與各自API特點以及使用場景說明

2.1ArrayBlockingQueue

@Testpublic void test02() throws Exception{ //必須指定隊列長度 ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<String>(2); abq.add('a'); //add :添加元素,如果BlockingQueue可以容納,則返回true,否則拋異常,支持添加集合 System.out.println(abq.offer('b'));//容量如果不夠,返回false //offer: 如果可能的話,添加元素,即如果BlockingQueue可以容納,則返回true,否則返回false,支持設置超時時間 //設置超時,如果超過時間就不添加,返回false, abq.offer('d', 2, TimeUnit.SECONDS);// 添加的元素,時長,單位 //put 添加元素,如果BlockQueue沒有空間,則調用此方法的線程被阻斷直到BlockingQueue里面有空間再繼續. abq.put('d');//會一直等待 //poll 取走頭部元素,若不能立即取出,則可以等time參數規定的時間,取不到時返回null,支持設置超時時間 abq.poll(); abq.poll(2,TimeUnit.SECONDS);//兩秒取不到返回null //take() 取走頭部元素,若BlockingQueue為空,阻斷進入等待狀態直到Blocking有新的對象被加入為止 abq.take(); //取出頭部元素,但不刪除 abq.element(); //drainTo() //一次性從BlockingQueue獲取所有可用的數據對象(還可以指定獲取數據的個數),通過該方法,可以提升獲取數據效率;不需要多次分批加鎖或釋放鎖。 List list=new ArrayList(); abq.drainTo(list,2);//將隊列中兩個元素取到list中,取走后隊列中就沒有取走的元素 System.out.println(list); //[a,b] System.out.println(abq); //[]}

2.2 LinkedBlockingQueue

@Testpublic void test03(){ LinkedBlockingQueue lbq=new LinkedBlockingQueue();//可指定容量,也可不指定 lbq.add('a'); lbq.add('b'); lbq.add('c'); //API與ArrayBlockingQueue相同 //是否包含 System.out.println(lbq.contains('a')); //移除頭部元素或者指定元素 remove('a') System.out.println(lbq.remove()); //轉數組 Object[] array = lbq.toArray(); //element 取出頭部元素,但不刪除 System.out.println(lbq.element()); System.out.println(lbq.element()); System.out.println(lbq.element());}

2.3 SynchronousQueue

public static void main(String[] args) { SynchronousQueue<String> sq=new SynchronousQueue<String>(); // iterator() 永遠返回空,因為里面沒東西。 // peek() 永遠返回null /** * isEmpty()永遠是true。 * remainingCapacity() 永遠是0。 * remove()和removeAll() 永遠是false。 */ new Thread(()->{try { //取出并且remove掉queue里的element(認為是在queue里的。。。),取不到東西他會一直等。 System.out.println(sq.take());} catch (InterruptedException e) { e.printStackTrace();} }).start(); new Thread(()->{try { //offer() 往queue里放一個element后立即返回, //如果碰巧這個element被另一個thread取走了,offer方法返回true,認為offer成功;否則返回false //true ,上面take線程一直在等, ////下面剛offer進去就被拿走了,返回true,如果offer線程先執行,則返回false System.out.println(sq.offer('b')); } catch (Exception e) { e.printStackTrace();} }).start(); new Thread(()->{try { //往queue放進去一個element以后就一直wait直到有其他thread進來把這個element取走 sq.put('a');} catch (Exception e) { e.printStackTrace();} }).start();}

2.4 PriorityBlockingQueue

@Testpublic void test04() throws Exception{ //隊列里元素必須實現Comparable接口,用來決定優先級 PriorityBlockingQueue<String> pbq=new PriorityBlockingQueue<String>(); pbq.add('b'); pbq.add('g'); pbq.add('a'); pbq.add('c'); //獲取的時候會根據優先級取元素,插入的時候不會排序,節省性能 //System.out.println(pbq.take());//a,獲取時會排序,按優先級獲取 System.out.println(pbq.toString());//如果前面沒有取值,直接syso也不會排序 Iterator<String> iterator = pbq.iterator(); while(iterator.hasNext()){System.out.println(iterator.next()); }}@Testpublic void test05(){ PriorityBlockingQueue<Person> pbq=new PriorityBlockingQueue<Person>(); Person p2=new Person('姚振',20); Person p1=new Person('侯征',24); Person p3=new Person('何毅',18); Person p4=new Person('李世彪',22); pbq.add(p1); pbq.add(p2); pbq.add(p3); pbq.add(p4); System.out.println(pbq);//沒有按優先級排序 try {//只要take獲取元素就會按照優先級排序,獲取一次就全部排好序了,后面就會按優先級迭代pbq.take(); } catch (InterruptedException e) {e.printStackTrace(); } //按年齡排好了序 for (Iterator iterator = pbq.iterator(); iterator.hasNext();) {Person person = (Person) iterator.next();System.out.println(person); }}

2.5 最后說一下DelayQueue ,這里用個網上很經典的例子,網吧上網計時

網民實體queue中元素

//網民public class Netizen implements Delayed { //身份證private String ID;//名字private String name;//上網截止時間private long playTime;//比較優先級,時間最短的優先@Overridepublic int compareTo(Delayed o) { Netizen netizen=(Netizen) o; return this.getDelay(TimeUnit.SECONDS)-o.getDelay(TimeUnit.SECONDS)>0?1:0;}public Netizen(String iD, String name, long playTime) { ID = iD; this.name = name; this.playTime = playTime;}//獲取上網時長,即延時時長@Overridepublic long getDelay(TimeUnit unit) { //上網截止時間減去現在當前時間=時長 return this.playTime-System.currentTimeMillis();}

網吧類:

//網吧public class InternetBar implements Runnable { //網民隊列,使用延時隊列private DelayQueue<Netizen> dq=new DelayQueue<Netizen>();//上網public void startPlay(String id,String name,Integer money){ //截止時間= 錢數*時間+當前時間(1塊錢1秒) Netizen netizen=new Netizen(id,name,1000*money+System.currentTimeMillis()); System.out.println(name+'開始上網計費......'); dq.add(netizen);}//時間到下機public void endTime(Netizen netizen){ System.out.println(netizen.getName()+'余額用完,下機');}@Overridepublic void run() { //線程,監控每個網民上網時長 while(true){try { //除非時間到.否則會一直等待,直到取出這個元素為止 Netizen netizen=dq.take(); endTime(netizen);}catch (InterruptedException e) { e.printStackTrace();} }}public static void main(String[] args) { //新建一個網吧 InternetBar internetBar=new InternetBar(); //來了三個網民上網 internetBar.startPlay('001','侯征',3); internetBar.startPlay('002','姚振',7); internetBar.startPlay('003','何毅',5);Thread t1=new Thread(internetBar);t1.start(); }}

這樣就可以完美實現業務需求了

結果

java中并發Queue種類與各自API特點以及使用場景說明,

這塊東西比較深,還需要不斷加強學習實踐才行!!

Java中的Queue和自定義堆棧Queue:單向

- 隊列通常 FIFO (先進先出)

- 優先級隊列和堆棧 LIFO (后進先出)

package com.bjsxt.others.que;import java.util.ArrayDeque;import java.util.Queue;/** * 使用隊列模擬銀行存款業務 * @author Administrator * */public class Demo01 { /** * @param args */ public static void main(String[] args) { Queue<Request> que =new ArrayDeque<Request>(); //模擬排隊情況 for(int i=0;i<10;i++){ final int num =i; que.offer(new Request(){//應用匿名內部類對象只能訪問 final 修飾的變量 @Override public void deposit() { System.out.println('第'+num+'個人,辦理存款業務,存款額度為:'+(Math.random()*10000)); } }); } dealWith(que); } //處理業務 public static void dealWith(Queue<Request> que){ Request req =null; while(null!=(req=que.poll())){ req.deposit(); } }}interface Request{ //存款 void deposit();}自定義堆棧

package com.bjsxt.others.que;import java.util.ArrayDeque;import java.util.Deque;/** * 使用隊列實現自定義堆棧 * 1、彈 * 2、壓 * 3、獲取頭 * @author Administrator * * @param <E> */public class MyStack<E> { //容器 private Deque<E> container =new ArrayDeque<E>(); //容量 private int cap; public MyStack(int cap) { super(); this.cap = cap; } //壓棧 public boolean push(E e){ if(container.size()+1>cap){ return false; } return container.offerLast(e); } //彈棧 public E pop(){ return container.pollLast(); } //獲取 public E peek(){ return container.peekLast(); } public int size(){ return this.container.size(); }} package com.bjsxt.others.que;//測試自定義堆棧public class Demo02 { /** * @param args */ public static void main(String[] args) { MyStack<String> backHistory =new MyStack<String>(3); backHistory.push('www.baidu.com'); backHistory.push('www.google.com'); backHistory.push('www.sina.com'); backHistory.push('www.bjsxt.cn'); System.out.println('大?。?+backHistory.size()); //遍歷 String item=null; while(null!=(item=backHistory.pop())){ System.out.println(item); } }}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
中国字幕a在线看韩国电影| 99国产精品免费视频观看| 亚洲天堂免费电影| 国产精品亚洲一区二区三区在线观看| 国产成人久久精品麻豆二区| 国产精品精品| 亚洲四虎影院| 亚洲精品美女91| 久久一区亚洲| 99久久亚洲精品| 亚洲最大av| 久久精品国产成人一区二区三区 | 美女毛片一区二区三区四区最新中文字幕亚洲| 婷婷五月色综合香五月| 国产精品国产三级在线观看| 天堂av在线| 免播放器亚洲| 美女视频黄免费的久久| 快播电影网址老女人久久| 亚洲尤物在线| 麻豆国产精品| 免费观看不卡av| 日本视频中文字幕一区二区三区| 精品高清久久| 国产视频一区免费看| 国产精品主播在线观看| 免费观看久久av| 国产精品99精品一区二区三区∴| 国产a久久精品一区二区三区| 欧美在线网站| 精品91福利视频| 911精品国产| 激情五月综合| 精品久久福利| 最新国产精品久久久| 免费看av不卡| 国产激情久久| 欧美一区=区| 久久久久国产精品一区二区| 国产精品一区二区99| 日韩精品一区第一页| 欧美~级网站不卡| 婷婷综合六月| 国产亚洲高清在线观看| 欧美日韩精品免费观看视频完整| 精品视频自拍| 久久精品 人人爱| 日本免费一区二区视频| 亚洲欧美日韩国产一区二区| 91视频一区| 久久久亚洲欧洲日产| 日韩av字幕| 国产精品综合色区在线观看| 亚洲影视一区| 伊人久久亚洲影院| 久久久久蜜桃| 四季av一区二区凹凸精品| 老鸭窝一区二区久久精品| 91精品国产自产精品男人的天堂| 欧洲一区二区三区精品| 韩国三级一区| 精品中国亚洲| 高清在线一区| 欧美日韩精品免费观看视欧美高清免费大片| 成人午夜在线| 日韩一区三区| 伊人久久成人| 在线精品观看| 中文字幕一区二区三区四区久久| 欧美专区18| 婷婷精品在线| 国产精品亚洲片在线播放| 精品国产亚洲一区二区三区| 欧美精品91| 国产在视频一区二区三区吞精| 精品一区二区三区中文字幕视频| 国产亚洲一卡2卡3卡4卡新区| 国产精品一区亚洲| 久久精品女人| 欧美日韩国产欧| 国产精品白浆| 欧美日韩国产免费观看视频| 中文字幕一区二区av| 红杏一区二区三区| 99国产精品视频免费观看一公开 | 欧美日韩亚洲一区在线观看| 国产精品久久久久久av公交车| 亚洲播播91| 日韩国产精品久久久久久亚洲| 欧美黑人做爰爽爽爽| 日韩免费av| 欧美视频二区| 91精品观看| 精品久久一区| 日韩一区二区三区在线看| 国产aa精品| 日韩有吗在线观看| 99成人超碰| 日韩高清一区在线| 午夜久久一区| 捆绑调教美女网站视频一区| 久久精品国产大片免费观看| **爰片久久毛片| 欧美肉体xxxx裸体137大胆| 国产精品宾馆| 中文字幕亚洲在线观看| 欧美日韩国产免费观看视频| 国产精品激情电影| 亚洲精品第一| 视频一区二区中文字幕| 久久精品亚洲人成影院| 国产精品亚洲欧美一级在线| 黑丝一区二区| 精品三级国产| 日韩精品a在线观看91| 国产精品日韩欧美一区| 91精品综合| 欧美精品一区二区久久| 成人啊v在线| 久久黄色影院| 久久精品国内一区二区三区水蜜桃| 精品一区二区三区在线观看视频| 日本欧美一区二区| 综合视频一区| 日韩影院在线观看| 午夜免费一区| 日韩视频不卡| 中文精品在线| 黄色av日韩| av不卡在线| 蜜桃视频在线观看一区二区| 9色国产精品| 亚洲综合图色| 日韩美女国产精品| 国产精品手机在线播放| 国产欧美三级| 久久精品国产免费| 久久精品国内一区二区三区水蜜桃| 欧美亚洲在线日韩| 国产高清一区| 久久电影一区| 日本视频在线一区| 免费视频一区二区三区在线观看 | 日韩福利在线观看| 久久精品国产精品亚洲毛片| 久久精品天堂| 婷婷激情图片久久| 亚洲3区在线| 久久在线91| 在线精品小视频| 国产丝袜一区| 99视频精品视频高清免费| 蜜桃视频在线观看一区二区| 国产欧美一区二区三区国产幕精品 | 亚洲免费高清| 亚洲乱码视频| zzzwww在线看片免费| 日韩免费看片| 天堂资源在线亚洲| 久久精品999| 一区免费视频| 欧美黄色一区| 亚洲欧美日本日韩| 欧美视频二区| 99国产一区| а√天堂中文在线资源8| 亚州精品视频| 久久国产精品成人免费观看的软件| 亚洲另类av| 激情六月综合| 97欧美在线视频| 亚洲精选av| 国产字幕视频一区二区| 精品视频在线你懂得| 亚洲精品在线二区| 欧美日韩日本国产亚洲在线| 色爱综合网欧美| 国产日韩免费| 免费的成人av| 日韩中文字幕一区二区三区| 日韩欧美精品| 美女视频网站久久| 国产精品一区高清| 日本精品另类| 婷婷久久免费视频| 蜜臀国产一区二区三区在线播放| 久久免费国产| 日本免费久久| 91偷拍一区二区三区精品| 国产极品模特精品一二| 日韩高清一级| 91亚洲精品视频在线观看| 免费观看在线综合色| 亚洲一级影院| 欧美jjzz| 蜜桃视频一区二区三区在线观看| 一区三区视频| 日韩中文字幕区一区有砖一区 | 日本亚州欧洲精品不卡| 伊人久久大香伊蕉在人线观看热v|