concurrent下的包

基本使用

0.ReetrantLock

可以同synchronized用,但是更加靈活,可以自己阻塞中斷,等待可放棄,可以使用基于公平鎖的機制,還可以實現(xiàn)分組喚醒。
原理:使用AQS的獨享鎖。
使用CAS加鎖,可以避免線程切換帶來的開銷,線程被阻塞后便進入內核(Linux)調度狀態(tài),這個會導致系統(tǒng)在用戶態(tài)與內核態(tài)之間來回切換,嚴重影響鎖的性能。

1.semaphore 信號量

Semaphore signal = new Semaphore(n);//可以放入n個信號量
通過signal.acquire()來獲取令牌。如果沒有令牌就阻塞;
通過signal.release()放回令牌。
//用于限制某種資源獲取,或者訪問數(shù)控制

2.cyclicBarrier

CyclicBarrier barrier=new CyclicBarrier(n,thread);//n個countdown執(zhí)行后繼續(xù)執(zhí)行thread里面的run方法
barrier.await();計數(shù)器 -1;
計數(shù)器為0執(zhí)行thread.

3.countDownLatch

CountDownLatch countDownLatch = new CountDownLatch(n);
countDownLatch.countDown();計數(shù)器減一
countDownLatch.await();判斷當前計數(shù)器狀態(tài),為0繼續(xù)

4.exchanger

Exchanger exchanger = new Exchanger();
exchanger.exchange();//等待偶數(shù)個對象進行exchange()方法,會將自己的數(shù)據(jù)與對方交換。如果另一個線程沒有執(zhí)行這個exchange(),則會一直等待
原理:
當線程A調用Exchange對象的exchange()方法后,他會陷入阻塞狀態(tài),直到線程B也調用了exchange()方法,然后以線程安全的方式交換數(shù)據(jù),之后線程A和B繼續(xù)運行。
原理:在競爭比較小的時候,采用單槽位進行交換數(shù)據(jù),當線程來交換數(shù)據(jù)時,發(fā)現(xiàn)槽位為空,則自己在這里等待,否則就和槽位進行交換數(shù)據(jù),同時會喚醒等待的線程。
在競爭比較激烈的情況下,就會轉到多槽位的交換,當一個線程來交換的時候,如果”第一個”槽位是空的,那么自己就在那里等待,如果發(fā)現(xiàn)”第一個”槽位有等待線程,那么就直接交換,如果交換失敗,說明其它線程在進行交換,那么就往后挪一個槽位,
如果有數(shù)據(jù)就交換,沒數(shù)據(jù)就等一會,但是不會阻塞在這里,在這里等了一會,發(fā)現(xiàn)還沒有其它線程來交換數(shù)據(jù),
那么就往“第一個”槽位的方向挪,如果反復這樣過后,挪到了第一個槽位,沒有線程來交換數(shù)據(jù)了,那么自己就在”第一個”槽位阻塞等待。
第一個槽位并不是指的數(shù)組中的第一個,而是邏輯第一個,因為存在偽共享,多槽位中,部分空間沒有被利用。

5.Phaser

繼承Phaser類。重寫onAdvance()方法,表示每階段完成之后回調的方法。
使用phaser.register()注冊的方法會互相等待到注冊的所有線程執(zhí)行完phaser.arriveAndAwaitAdvance();調用這個繼承類里phaser的數(shù)值從0開始的方法。然后釋放,再等他們調用phaser.arriveAndAwaitAdvance();繼續(xù)phaser為1的調用,知道pharser return 為 true;
實例可見 :https://blog.csdn.net/u010739551/article/details/51083004/
原理:

4.DIFF:2.3比較相似,區(qū)別:

(1).CountDownLatch 的作用是允許1或者多個線程,等待另外N個線程完成某件事情之后,這1個或者多個線程才能執(zhí)行。CyclicBarrier 是N個線程相互等待,任何一個線程完成任務之前,所有的線程必須等待。
(2).CountDownLatch 計數(shù)器是一次性的,無法被重置的,而CyclicBarrier的計數(shù)器在調用reset方法之后,還可以重新使用,因此被稱為循環(huán)的barrier。


原理

都是使用的AQS這個FIFO的隊列.
他們都是使用state這個作為計數(shù)器。

AQS

是一個先進先出的隊列。
主要組成:volatile int state(代表共享資源)和一個FIFO線程等待隊列(多線程爭用資源被阻塞時會進入此隊列)
在隊列里的頭節(jié)點是個傀儡節(jié)點
為啥要在這里用一個傀儡節(jié)點:
這個與后面文章的內容acquireQueue方法中入隊操作有關。Q1問題提到了AQS借用了CLH的思想,也就是不斷對前驅節(jié)點的狀態(tài)進行訪問。那么在判斷是否可以獲取資源時,也需要再次訪問前驅節(jié)點。如果初始化的時候不將頭節(jié)點賦值為空節(jié)點,那么前驅節(jié)點為null,這個與不是初始化階段的隊列情況不同,勢必會復雜后面的流程。這也是AQS的簡單優(yōu)化之一。
主要分為共享模式和獨占模式。
獨占模式:CountDownLatch,semaphore
共享模式:ReetrantLock

區(qū)別:
獨占鎖只有頭節(jié)點可以獲取到鎖。
共享的時候,從獲取共享鎖的節(jié)點然后向后不斷傳遞喚醒。

參考文章:
https://blog.csdn.net/qingtian211/article/details/81316067
http://www.itdecent.cn/p/63588ebea397

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容