併發包中ReentrantLock的建立能夠指定構造函數的boolean類型來獲得公平鎖或者非公平鎖,默認是非公平鎖java
公平鎖
:在併發環境中,每一個線程在獲取鎖時會先查看此鎖維護的等待隊列,若是爲空,或者當前線程是等待隊列中的第一個,就佔用鎖,不然就會加入到等待隊列中,之後會按照FIFO的規則從隊列中等待被取到。api
非公平鎖
:非公平鎖比較粗魯上來就直接嘗試佔有鎖,若是嘗試失敗,就在採用相似公平鎖的方式在隊列中等待被取到。併發
對於java ReentrantLock而言,經過構造函數指定該鎖是否爲公平鎖,默認是非公平鎖
。非公平鎖的優勢自安於吞吐量比公平鎖大。jvm
對於synchronized而言,也是一種非公平鎖函數
可重入鎖又叫遞歸鎖,典型的可重入鎖有ReentrantLock/Synchronized。指的是統一鮮橙外層函數得到鎖以後,內層度規函數仍然能獲取該鎖的代碼,同一個線程在外層方法獲取鎖的時候,在進入內層方法會自動獲取鎖
也就是說,線程能夠進入任何一個他已經擁有的鎖所同步着的代碼塊。post
public synchronized void method01(){
method02();
}
public synchronized void method02(){
}
複製代碼
如以上代碼,若是一個線程擁有method01的鎖,那麼會自動擁有method02的鎖,這樣看,可重入鎖最大的做用是避免死鎖this
可參考上篇文章介紹的CAS的加鎖方式atom
public final int getAndSetInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var4));
return var5;
}
複製代碼
自旋鎖是指獲取鎖的線程不會當即阻塞,而是採用循環的方式去嘗試獲取鎖直至成功爲止,沒有相似wait的阻塞,這樣的好處是減小線程上下文切換的消耗,缺點是循環會消耗CPUspa
手動實現一個自旋鎖:線程
public void myLock(){
Thread thread = Thread.currentThread();
System.out.println(thread +": come in lock");
while (!atomicReference.compareAndSet(null,thread)){
}
}
public void unLock(){
Thread thread = Thread.currentThread();
System.out.println(thread + ": come in unlock");
while (!atomicReference.compareAndSet(thread,null)){
}
}
複製代碼
當A線程調用myLock時,thread爲null,因此atomicReference.compareAndSet(null,thread)成立,取反跳出循環,這時atomicReference內Thread爲A的線程,B線程同時也調用myLock方法時,由於指望值爲null,其實是A線程,結果不成立,因此一直在while中循環;A線程再調用unlock方法,指望值是A本身的線程,而後設置爲null,返回true而後取反,跳出循環,B線程不斷地在mylock中循環,忽然讀到指望值爲null了,知足本身的需求,而後跳出循環,這時加鎖成功。
獨佔鎖:該鎖一次只能被一個線程所持有,ReentrantLock和Synchronized都是獨佔鎖
共享鎖:該鎖可被多個線程所持有。 ReentrantReadWriteLock中的讀鎖是共享鎖,其寫鎖是獨佔鎖。 讀鎖的共享鎖可保證併發讀是很是高效的,讀寫,寫讀,寫寫的過程是互斥的。
讓一些線程阻塞直到另外一些線程完成一系列操做後才被喚醒 CountDownLatch主要有兩個方法,當一個或多個線程調用await方法時,調用線程會被阻塞。其餘線程調用countDown方法會將計數器減1(調用countDown方法的線程不會被阻塞),當計數器的值變成零時,因調用await方法被阻塞的線程會被喚醒,繼續執行。
CyclicBarrier意思Wie可循環使用的屏障。主要功能是讓一組線程到達一個屏障點(也能夠叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障纔會開門,被屏障攔截的線程纔會繼續幹活,線程進入屏障經過CyclicBarrier的await()方法。 demo: 集齊7顆龍珠才能召喚神龍
Semaphore 信號量,主要用於兩個目的,一個是用於多個共享資源的互斥使用,另外一個用於併發線程數的控制。