Lock在咱們平常研發中常常會使用到,好比ReenTrantLock,ReentrantReadWriteLock,StampedLock (JDK1.8新增),java
下面就詳細介紹一下它們的使用方法。bash
ReenTrantLock支持公平鎖和非公平鎖,也是獨佔鎖,下面來講一下ReenTrantLock下的方法和使用。多線程
**lock:**獲取阻塞鎖。ui
// 默認是費公平鎖,可自定,在參數中增長 true-公平 false-非公平
ReenTrantLock lockObjcet = new ReenTrantLock();
try {
// 獲取鎖 ,若是獲取不到則阻塞線程
lockObjcet.lock();
// 同步代碼塊
} catch (Exception e) {
} finally {
// 釋放鎖
lockObjcet.unLock();
}
複製代碼
**tryLock:**獲取非阻塞鎖,若是沒法獲取到鎖,返回false,獲取到了返回true。spa
複製代碼
ReenTrantLock lock = new ReenTrantLock(); if (lock.tryLock()) { // 獲取到了鎖 } else { // 沒有獲取到鎖 }線程
3. **tryLock(time):**獲取非阻塞超時鎖,在time時間內若是獲取到了鎖,返回true,獲取不到鎖返回false。
```java
ReenTrantLock lock = new ReenTrantLock();
// 獲取鎖,若是在指定時間內還未得到,則返回false
if (lock.tryLock(100)) {
// 獲取到了鎖
} else {
// 沒有獲取到鎖
}
複製代碼
讀寫鎖: 讀鎖能夠多線程一塊兒獲取,寫鎖只有一個線程能夠獲取,讀寫鎖支持公平鎖和非公平鎖,支持重入鎖。code
讀鎖: 能夠被多個線程共同獲取鎖,同時進入代碼塊。blog
寫鎖:只容許一個線程獲取,若是當前線程獲取到寫鎖後,發現有線程獲取了讀鎖,而且不是當前線程,這時當前線程就進入等待狀態。隊列
代碼示例:ip
// 讀寫鎖
private ReadWriteLock rw = new ReentrantReadWriteLock();
// 讀鎖 共享鎖
private Lock r = rw.readLock();
// 寫鎖 排它鎖
private Lock w = rw.writeLock();
複製代碼
StampedLock: 讀寫鎖,可是StampedLock比ReenTrantReadWriteLock更塊,可是StampedLock用於樂觀讀鎖,悲觀讀鎖,和寫鎖,StampedLock不支持重入鎖,StampedLock 的悲觀讀鎖、寫鎖都不支持條件變量。
代碼示例:
/** * @Auther: lantao * @Date: 2019-05-05 17:55 * @Company: 隨行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */
public class StampedLockTest {
static StampedLock s =new StampedLock();
public static void main(String[] args) {
// 悲觀讀
long l = s.readLock();
// 釋放悲觀讀
s.unlockRead(l);
// 悲觀寫
long l1 = s.writeLock();
// 釋放悲觀寫
s.unlockWrite(l1);
// 樂觀讀 升級 悲觀讀
long l2 = s.tryOptimisticRead();
//驗證是否被修改 若是返回false 會釋放 l2,因此後續直接釋放l3便可
if (!s.validate(l2)){
// 升級悲觀讀
long l3 = s.readLock();
s.unlockRead(l3);
}
}
}
複製代碼
Condition: Lock 的條件 ,其實初始化的是ConditionObject, ConditionObject是Condition的實現,singal和signlAll的時候須要在獲取鎖後。
代碼示例:
/** * @Auther: lantao * @Date: 2019-04-15 14:49 * @Company: 隨行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: Condition 條件 有 singal signalAll 和 await 方法 和Object 的 notify notifyAll 和 wait 是一個意思一樣會釋放鎖 執行singal和notify的時候也須要在等待獲取鎖 */
public class LockCondition {
public static ReentrantLock lock = new ReentrantLock();
public static Condition a = lock.newCondition();
public static Condition b = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Runnable runnable = () -> {
try {
lock.lock();
System.out.println(Thread.currentThread().getName());
a.await();
System.out.println(Thread.currentThread().getName() + " 的 a conndition 被喚醒了");
b.await();
System.out.println(Thread.currentThread().getName() + " 的 b conndition 被喚醒了");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
};
Runnable runnable1 = () -> {
try {
lock.lock();
System.out.println("線程" +Thread.currentThread().getName() + " 開始執行a condition sinalAll");
a.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
};
Runnable runnable2 = () -> {
try {
lock.lock();
System.out.println("線程" +Thread.currentThread().getName() + " 開始執行b condition sinalAll");
b.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
};
new Thread(runnable,"Thread1").start();
new Thread(runnable,"Thread2").start();
Thread.sleep(100);
new Thread(runnable1,"Thread3").start();
Thread.sleep(100);
new Thread(runnable2,"Thread4").start();
}
}
// 執行結果
Thread1
Thread2
線程Thread3 開始執行a condition sinalAll
Thread1 的 a conndition 被喚醒了
Thread2 的 a conndition 被喚醒了
線程Thread4 開始執行b condition sinalAll
Thread1 的 b conndition 被喚醒了
Thread2 的 b conndition 被喚醒了
複製代碼
博客地址:lantaoblog.site