[TOC]
## ReentrantLock獨享式重入鎖
### 使用
~~~
ReentrantLock takeLock = new ReentrantLock();
// 獲取鎖
takeLock.lock();
try {
// 業務邏輯
} finally {
// 釋放鎖
takeLock.unlock();
}
~~~
## ReentrantReadWriteLock 讀寫分離獨享式重入鎖
因此理想的實現是:
1. 當有寫線程時,則寫線程獨占同步狀態。
2. 當沒有寫線程時只有讀線程時,則多個讀線程可以共享同步狀態。
~~~
public class ReadWriteCache {
private static Map<String, Object> data = new HashMap<>();
private static ReadWriteLock lock = new ReentrantReadWriteLock(false);
private static Lock rlock = lock.readLock();
private static Lock wlock = lock.writeLock();
public static Object get(String key) {
rlock.lock();
try {
return data.get(key);
} finally {
rlock.unlock();
}
}
public static Object put(String key, Object value) {
wlock.lock();
try {
return data.put(key, value);
} finally {
wlock.unlock();
}
}
~~~
## Semaphore共享式不可重入鎖
~~~
// 創建一個計數閾值為5的信號量對象
// 只能5個線程同時訪問
Semaphore semp = new Semaphore(5);
try {
// 申請許可
semp.acquire();
try {
// 業務邏輯
} catch (Exception e) {
} finally {
// 釋放許可
semp.release();
}
} catch (InterruptedException e) {
~~~
## CountDownLatch計數式獨享鎖
## Condition等待通知
1. 每當一個線程調用Condition.await()方法,那么該線程會釋放鎖,構造成一個Node節點加入到等待隊列的隊尾。
2. 每當一個線程調用Condition.signal()方法,那么該線程會等待隊列的隊尾節點移到AQS中
### Condition原理
Condition實現等待的時候內部也有一個等待隊列,等待隊列是一個隱式的單向隊列,等待隊列中的每一個節點也是一個AbstractQueuedSynchronizer.Node實例。
每個Condition對象中保存了firstWaiter和lastWaiter作為隊列首節點和尾節點,每個節點使用Node.nextWaiter保存下一個節點的引用,因此等待隊列是一個單向隊列。
每當一個線程調用Condition.await()方法,那么該線程會釋放鎖,構造成一個Node節點加入到等待隊列的隊尾。
每當一個線程調用Condition.signal()方法,那么該線程會等待隊列的隊尾節點移到AQS中
- Java
- Object
- 內部類
- 異常
- 注解
- 反射
- 靜態代理與動態代理
- 泛型
- 繼承
- JVM
- ClassLoader
- String
- 數據結構
- Java集合類
- ArrayList
- LinkedList
- HashSet
- TreeSet
- HashMap
- TreeMap
- HashTable
- 并發集合類
- Collections
- CopyOnWriteArrayList
- ConcurrentHashMap
- Android集合類
- SparseArray
- ArrayMap
- 算法
- 排序
- 常用算法
- LeetCode
- 二叉樹遍歷
- 劍指
- 數據結構、算法和數據操作
- 高質量的代碼
- 解決問題的思路
- 優化時間和空間效率
- 面試中的各項能力
- 算法心得
- 并發
- Thread
- 鎖
- java內存模型
- CAS
- 原子類Atomic
- volatile
- synchronized
- Object.wait-notify
- Lock
- Lock之AQS
- Lock子類
- 鎖小結
- 堵塞隊列
- 生產者消費者模型
- 線程池