1 J.U.C簡介
- java.util.concurrent 簡稱,java并發(fā)工具包
- 線程池
- 阻塞隊(duì)列
- 計(jì)時器/同步器
- 并發(fā)集合
2 Lock的基本使用
-
synchronized
不夠靈活,鎖的釋放無法人為控制,只能等待同步代碼塊執(zhí)行完成或發(fā)生異常 -
Lock
java.util.concurrent.locks 包下的接口,提供了鎖的獲得與釋放的接口方法,在JUC中存在眾多實(shí)現(xiàn)
3 ReentranLock重入鎖
- 同一線程 通過
Lock.lock()
獲得重入鎖,當(dāng)此線程再次調(diào)用時不會被阻塞可以進(jìn)入,即:同一線程"一次鎖定多次進(jìn)入",其它線程此時調(diào)用進(jìn)行阻塞 -
synchronized
也支持重入 -
ReentranLock
重入鎖的設(shè)計(jì)目的是為了解決死鎖
public class ThreadDemo1 {
public synchronized void func1(){//獲取對象鎖
System.out.println("func1");
func2();
}
public void func2(){
synchronized (this){//同一線程,同一把鎖允許重入,增加重入次數(shù),并沒有死鎖
System.out.println("func2");
}//同步代碼執(zhí)行完成,減少重入次數(shù)
}
public static void main(String[] args) {
ThreadDemo1 demo1 = new ThreadDemo1();
demo1.func1();
}
}
public class ThreadDemo2 {
//重入鎖
static Lock LOCK = new ReentrantLock();
public void func1(){
LOCK.lock();//獲得重如鎖
//....
LOCK.unlock();//釋放重入鎖
}
}
4 讀寫鎖ReentrantReadWriteLock
- 適用于讀多寫少的操作,例如緩存更新
- 讀鎖&讀鎖->可重入
- 讀鎖&寫鎖(寫鎖&讀鎖)->阻塞不可重入
public class ThreadDemo3 {
//讀寫鎖
static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//讀鎖
static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
//寫鎖
static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//緩存
static Map<String,Object> cache = new HashMap<String, Object>();
/**
* Description:根據(jù)key從緩存中獲取對象
* @Param [key]
* @return java.lang.Object
**/
public final Object getFromCache(String key){
readLock.lock();//獲取'讀鎖'
try {
return cache.get(key);
} finally {
readLock.unlock();//釋放'讀鎖'
}
}
/**
* Description:向緩存中添加對象
* @Param [key, value]
* @return void
**/
public void putToCache(String key,final Object value){
writeLock.lock();//獲取'寫鎖'
try {
cache.put(key,value);
} finally {
writeLock.unlock();//釋放'寫鎖'
}
}
}
5 AQS原理分析
- 同步工具
ReentrantLock 中AQS實(shí)現(xiàn)原理
ReentrantLock.Sync(內(nèi)部類).lock()
Sync有兩個子類
FairSync-公平鎖(不允許插隊(duì))
NonfairSync-非公平鎖(允許插隊(duì))
分別重寫了lock()方法