摘要:下面列出來(lái)一些常用的方法。延遲元素線程安全列表里面存放著帶有日期的元素,當(dāng)我們從列表獲取數(shù)據(jù)的時(shí)候,未到時(shí)間的元素將會(huì)被忽略。
前言在我們的程序開(kāi)發(fā)過(guò)程中,如果涉及到多線程環(huán)境,那么對(duì)于集合框架的使用就必須更加謹(jǐn)慎了,因?yàn)榇蟛糠值募项愒诓皇┘宇~外控制的情況下直接在并發(fā)環(huán)境中直接使用可能會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,所以為了解決這個(gè)潛在的問(wèn)題,我們要么在自己的業(yè)務(wù)邏輯中加上一些額外的控制,例如鎖,或者我們直接使用Java提供的可在并發(fā)環(huán)境中使用的集合類,這是一個(gè)簡(jiǎn)便而且高效的方法。那么我們下面就來(lái)了解下Java提供了哪些“神器”可以讓我們安全的使用集合。
正文ConcurrentLinkedDeque可以在并發(fā)環(huán)境中直接使用,所謂的非阻塞,就是當(dāng)列表為空的時(shí)候,我們還繼續(xù)從列表中取數(shù)據(jù)的話,它會(huì)直接返回null或者拋出異常。下面列出來(lái)一些常用的方法。
peekFirst()、peekLast() :返回列表中首位跟末尾元素,如果列表為空則返回null。返回的元素不從列表中刪除。
getFirst()、getLast() :返回列表中首位跟末尾元素,如果列表為空則拋出NoSuchElementExceotion異常。返回的元素不從列表中刪除。
removeFirst()、removeLast() :返回列表中首位跟末尾元素,如果列表為空則拋出NoSuchElementExceotion異常。【返回的元素會(huì)從列表中刪除】。
LinkedBlockingDeque是一個(gè)阻塞式的線程安全列表,它跟 ConcurrentLinkedDeque最大的區(qū)別就是,當(dāng)列表中元素滿了或者為空的時(shí)候,我們對(duì)該列表的操作不會(huì)立即返回,而是阻塞當(dāng)前操作,直到該操作可以執(zhí)行時(shí)才返回。我們對(duì)比著上面ConcurrentLinkedDeque的常用方法,來(lái)看下LinkedBlockingDeque會(huì)有哪些不一致的地方呢?
put() :插入元素至列表中,當(dāng)表中元素已滿的時(shí)候,該操作將會(huì)被阻塞,直到表中存在空余空間。
take() : 從列表中獲取元素,當(dāng)列表為空,該操作會(huì)被阻塞,直到列表不為空。
peekFirst()、peekLast() :返回列表中首位跟末尾元素,如果列表為空則返回null。返回的元素不從列表中刪除。
getFirst()、getLast() :返回列表中首位跟末尾元素,如果列表為空則拋出NoSuchElementExceotion異常。返回的元素不從列表中刪除。
addFirst()、addLast() :將元素添加至首位跟末尾,如果列表已滿,則會(huì)拋出IllegalStateException
可以看出不管是從獲取還是插入元素,都多了不少“花樣”,其差別就在于是否阻塞,不滿足條件是否返回null,不滿足條件是否拋異常這幾個(gè)方面來(lái)區(qū)分。
相信大家都寫(xiě)過(guò)把某個(gè)列表元素按照特定的規(guī)則來(lái)排序之類的代碼,在PriorityBlockingQueue中,存放進(jìn)去的元素必須要實(shí)現(xiàn)Comparable接口。在這個(gè)接口中,有一個(gè)compareTo()方法,當(dāng)執(zhí)行該方法的對(duì)象跟參數(shù)傳入的對(duì)象進(jìn)行比較的時(shí)候,這個(gè)方法會(huì)返回一個(gè)數(shù)字值,如果值小于0,則當(dāng)前對(duì)象小于參數(shù)傳入對(duì)象。大于0則相反,等于0就表示兩個(gè)對(duì)象相等。
public class DemoObj implements Comparable<DemoObj> {
private int priority;
@Override
public int compareTo(DemoObj do){
if(this.getPriority() > do.getPriority()){
return -1;
}else if(this.getPriority() < do.getPriority()){
return 1;
}
return 0;
}
//省略getset ...
}
//==== use ===================
PriorityBlockingQueue queue = new PriorityBlockingQueue()<>;
queue.put(DemoObj);
queue.peek();
其常用方法跟上面提到的類基本都差不多大家可以動(dòng)手實(shí)現(xiàn)一下,簡(jiǎn)單對(duì)比的話,可以說(shuō)是LinkedBlockingDeque的增強(qiáng)版,多了元素排序功能。
DelayQueue 里面存放著帶有日期的元素,當(dāng)我們從列表獲取數(shù)據(jù)的時(shí)候,未到時(shí)間的元素將會(huì)被忽略。因此,存放進(jìn)來(lái)的元素必須實(shí)現(xiàn)Delayed接口,使之成為一個(gè)延遲對(duì)象。
/**
* compareTo方法與getDelay方法需排序一致
*/
class Order implements Delayed{
private String name ;
private long start = System.currentTimeMillis();
private long time ;
public MyDelayedTask(String name,long time) {
this.name = name;
this.time = time;
}
/**
* 需要實(shí)現(xiàn)的接口,獲得延遲時(shí)間 用過(guò)期時(shí)間-當(dāng)前時(shí)間
* @param unit
* @return
*/
@Override
public long getDelay(TimeUnit unit) {
return unit.convert((start+time) - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
}
/**
* 延遲隊(duì)列內(nèi)部排序 當(dāng)前對(duì)象延遲時(shí)間 - 入?yún)?duì)象的延遲時(shí)間
* @param o
* @return
*/
@Override
public int compareTo(Delayed o) {
Order o1 = (Order) o;
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o1.getDelay(TimeUnit.MILLISECONDS));
}
}
使用方式如下
private static DelayQueue delayQueue = new DelayQueue();
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
delayQueue.offer(new Order("t3000",3000));
delayQueue.offer(new Order("t4000",4000));
delayQueue.offer(new Order("t2000",2000));
delayQueue.offer(new Order("t6000",6000));
delayQueue.offer(new Order("t1000",1000));
}
}).start();
while (true) {
Delayed take = delayQueue.take();
}
}
關(guān)于結(jié)果的輸出大家可以動(dòng)手嘗試一下~
結(jié)語(yǔ)這里僅僅是介紹了幾種常用的并發(fā)集合,其目的主要是讓大家對(duì)這些集合有一個(gè)直觀的認(rèn)識(shí),在使用的時(shí)候可以思考下自己的場(chǎng)景用哪種更合適,如果當(dāng)前介紹的類沒(méi)合適的,那么是否還有其他并發(fā)集合會(huì)更有用呢?這里就當(dāng)做拋磚引玉吧,有興趣的朋友可以多去了解一下相關(guān)技術(shù),相信你會(huì)有不少收獲的。
公眾號(hào)博文同步Github倉(cāng)庫(kù),有興趣的朋友可以幫忙給個(gè)Star哦,碼字不易,感謝支持。
github.com/PeppaLittle…
《如何優(yōu)化代碼中大量的if/else,switch/case");
《如何提高使用Java反射的效率?》
《Java日志正確使用姿勢(shì)》
關(guān)注「深夜里的程序猿」,分享最干的干貨
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/6748.html
摘要:下面列出來(lái)一些常用的方法。延遲元素線程安全列表里面存放著帶有日期的元素,當(dāng)我們從列表獲取數(shù)據(jù)的時(shí)候,未到時(shí)間的元素將會(huì)被忽略。 前言 在我們的程序開(kāi)發(fā)過(guò)程中,如果涉及到多線程環(huán)境,那么對(duì)于集合框架的使用就必須更加謹(jǐn)慎了,因?yàn)榇蟛糠值募项愒诓皇┘宇~外控制的情況下直接在并發(fā)環(huán)境中直接使用可能會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,所以為了解決這個(gè)潛在的問(wèn)題,我們要么在自己的業(yè)務(wù)邏輯中加上一些額外的控制,例如鎖...
摘要:下面列出來(lái)一些常用的方法。延遲元素線程安全列表里面存放著帶有日期的元素,當(dāng)我們從列表獲取數(shù)據(jù)的時(shí)候,未到時(shí)間的元素將會(huì)被忽略。 前言 在我們的程序開(kāi)發(fā)過(guò)程中,如果涉及到多線程環(huán)境,那么對(duì)于集合框架的使用就必須更加謹(jǐn)慎了,因?yàn)榇蟛糠值募项愒诓皇┘宇~外控制的情況下直接在并發(fā)環(huán)境中直接使用可能會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,所以為了解決這個(gè)潛在的問(wèn)題,我們要么在自己的業(yè)務(wù)邏輯中加上一些額外的控制,例如鎖...
摘要:這里呢,我直接給出高并發(fā)場(chǎng)景通常都會(huì)考慮的一些解決思路和手段結(jié)尾如何有效的準(zhǔn)備面試中并發(fā)類問(wèn)題,我已經(jīng)給出我的理解。 showImg(https://segmentfault.com/img/bV7Viy?w=550&h=405); 主題 又到面試季了,從群里,看到許多同學(xué)分享了自己的面試題目,我也抽空在網(wǎng)上搜索了一些許多公司使用的面試題,目前校招和社招的面試題基本都集中在幾個(gè)大方向上...
閱讀 2135·2021-10-14 09:43
閱讀 2197·2019-08-30 15:55
閱讀 726·2019-08-30 14:23
閱讀 2019·2019-08-30 13:21
閱讀 1235·2019-08-30 12:50
閱讀 2199·2019-08-29 18:46
閱讀 2280·2019-08-29 17:28
閱讀 2359·2019-08-29 17:21