synchronized原理可以參考此篇文章
ReentrantLock與synchronized的比較
- 共同點
- 二者都屬於可重入鎖、獨佔鎖(即不同線程之間的訪問是互斥的)
- 不同點
- synchronized加鎖與解鎖是隱試的ReentrantLock是顯示的
- synchronized不可響應中斷,一個線程獲取不到鎖就一直等着,ReentrantLock可以相應中斷(使用
lockInterruptibly()
方法加鎖)
- synchronized是非公平鎖,ReentrantLock可以通過過程函數傳入參數指定鎖是否是公平鎖,所謂公平鎖就是誰等待時間長誰先獲取鎖,非公平鎖就線程之間自由競爭隨機佔用鎖
- ReentrantLock有嘗試獲取鎖的方法
tryLock()
- 鎖處於空閒:返回true,將鎖持有者設置爲1
- 當前線程持有鎖(可重入鎖):返回true,同時將鎖持有者加1
- 其他線程持有鎖:返回false
public class MyReentrantLock {
private static ReentrantLock lock1 = new ReentrantLock();
private static ReentrantLock lock2 = new ReentrantLock();
public static void main(String[] args) {
new Thread(()->{
lock1.lock();
},"Thread-1").start();
new Thread(()->{
boolean b = lock1.tryLock();
System.out.println(b);
},"Thread-2").start();
new Thread(()->{
lock2.lock();
boolean b = lock2.tryLock();
System.out.println(b);
},"Thread-3").start();
}
}
關於ReentrantLock需要注意的點
- 釋放鎖的操作務必放在finally代碼塊裏
- 由於ReentrantLock是可重入鎖,因此要特別注意加鎖與釋放鎖的次數要一直
public class MyReentrantLock {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock(true);
lock.lock();
try {
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}