高併發(16)-顯示鎖Lock
前言
上篇文章講解了AQS,今天就講講顯示鎖Lock
什麼是Lock
Lock是一接口,實現了鎖功能的接口,基於AQS來實現的。
lock的兩大根接口,Lock和ReadWriteLock。
在Lock之前,java通過synchronized來實現鎖功能的,在JDK15之後,併發包多了個Lock接口還有其實現來實現鎖功能。
Lock的實現方式
因爲Lock是一個接口,所以需要對應的實現,
java的併發提供了Lock的實現類ReentrantLock(可重入鎖)。
ReadWriteLock(讀寫鎖)的現類是ReentrantReadWriteLock。
Lock與synchronized的區別
1. synchronized是java中的一個關鍵字,也就是說是Java語言內置的特性
Lock是接口,它下面有很多的實現類。
2. synchronize會自動釋放鎖
Lock需要‘手動’釋放。
3. synchronize不知道線程有沒有獲取到鎖
lock可以知道是否獲取到鎖
4、synchronize是非公平鎖
lock可以是公平鎖,也可以是非公平鎖。
5、synchronize等待不中斷
lock等待可中斷。
6、synchronize可以鎖對象、類、代碼塊
而lock鎖住的是代碼塊。
Lock代碼實現
/**
* @version 1.0
* @Description LockDemo
* @Author wb.yang
*/
public class LockDemo {
/**
* 創建一個lock鎖
*/
private static Lock lock = new ReentrantLock();
/**
* 計數值
*/
private static int count = 0;
public static class CountThread extends Thread {
@Override
public void run() {
// 獲得鎖
lock.lock();
try {
//業務操作
count++;
} finally {
//釋放鎖
lock.unlock();
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new CountThread().start();
}
SleepTools.second(2);
System.out.println(count);
}
}
在代碼中我們也可以看出,我們先是創建了一個lock,然後還有一個count變量。
接下來定義了一個線程方法,在方法中使用lock()方法,來獲取鎖,當只有獲得鎖後纔會繼續往下執行,然後執行業務操作,最後在finally 中釋放鎖。
然後在main方法中創建了1000個線程執行對count++,如果線程是不安全的話,那麼結果是不正確的
然後看下運行結果,從結果中可以看出,正好是1000,說明我們的加鎖成功,保證了線程的安全