Java多執行緒/併發10、不可重入鎖/自旋鎖、可重入鎖
鎖分為可重入鎖和不可重入鎖。
可重入和不可重入的概念是這樣的:當一個執行緒獲得了當前例項的鎖,並進入方法A,這個執行緒在沒有釋放這把鎖的時候,能否再次進入方法A呢?
- 可重入鎖:可以再次進入方法A,就是說在釋放鎖前此執行緒可以再次進入方法A(方法A遞迴)。
- 不可重入鎖(自旋鎖):不可以再次進入方法A,也就是說獲得鎖進入方法A是此執行緒在釋放鎖錢唯一的一次進入方法A。
先舉例來說明鎖的可重入性:
public class UnReentrant{
Lock lock = new Lock();
public void outer(){
lock.lock();
inner();
lock.unlock();
}
public void inner(){
lock.lock();
//do something
lock.unlock();
}
}
outer中呼叫了inner,outer先鎖住了lock,這樣inner就不能再獲取lock。其實呼叫outer的執行緒已經獲取了lock鎖,但是不能在inner中重複利用已經獲取的鎖資源,這種鎖即稱之為 不可重入 。通常也稱為 自旋鎖 。相對來說,可重入就意味著:執行緒可以進入任何一個它已經擁有的鎖所同步著的程式碼塊。
不可重入鎖基本原理:
可以看到,當isLocked被設定為true後,線上程呼叫unlock()解鎖之前不管執行緒是否已經獲得鎖,都只能wait()。
程式碼如下:
public class Lock{
private boolean isLocked = false;
public synchronized void lock()
throws InterruptedException{
while(isLocked){
wait();
}
isLocked = true;
}
public synchronized void unlock(){
isLocked = false;
notify();
}
}
可重入鎖的基本原理
我們修改Lock,加入一個變數lockBy用來儲存已經獲得鎖的執行緒,這樣就能對有鎖的執行緒放行。
public class Lock{
boolean isLocked = false;
Thread lockedBy = null;
int lockedCount = 0;
public synchronized void lock() throws InterruptedException{
Thread callingThread = Thread.currentThread();
while(isLocked && lockedBy != callingThread){
wait();
}
isLocked = true;
lockedCount++;
lockedBy = callingThread;
}
public synchronized void unlock(){
if(Thread.curentThread() == this.lockedBy){
lockedCount--;
if(lockedCount == 0){
isLocked = false;
notify();
}
}
}
}
解釋一下程式中的兩個變數:
lockBy:儲存已經獲得鎖例項的執行緒,在lock()判斷呼叫lock的執行緒是否已經獲得當前鎖例項,如果已經獲得鎖,則直接跳過while,無需等待。
lockCount:記錄同一個執行緒重複對一個鎖物件加鎖的次數。否則,一次unlock就會解除所有鎖,即使這個鎖例項已經加鎖多次了。
在java 中,synchronized和java.util.concurrent.locks.ReentrantLock是可重入鎖。
相關文章
- 可重入鎖與不可重入鎖理解
- Java併發-顯式鎖篇【可重入鎖+讀寫鎖】Java
- java中如何實現可重入的自旋鎖Java
- 可重入鎖
- 死鎖和可重入鎖
- 多執行緒高併發程式設計(2) -- 可重入鎖介紹和自定義執行緒程式設計
- Java 中15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等Java
- redis分散式鎖-可重入鎖Redis分散式
- ZooKeeper 分散式鎖 Curator 原始碼 03:可重入鎖併發加鎖分散式原始碼
- 【java併發程式設計】ReentrantLock 可重入讀寫鎖Java程式設計ReentrantLock
- java重入鎖、公平鎖和非公平鎖Java
- Java併發程式設計之鎖機制之(ReentrantLock)重入鎖Java程式設計ReentrantLock
- Java併發基礎-鎖的使用及原理(可重入鎖、讀寫鎖、內建鎖、訊號量等)Java
- 可重入鎖原始碼分析原始碼
- 執行緒安全: 互斥鎖和自旋鎖(10種)執行緒
- Redisson 分散式鎖原始碼 01:可重入鎖加鎖Redis分散式原始碼
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等...Java
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等Java
- 自旋鎖、阻塞鎖、可重入鎖、悲觀鎖、樂觀鎖、讀寫鎖、偏向所、輕量級鎖、重量級鎖、鎖膨脹、物件鎖和類鎖物件
- Java 重入鎖 ReentrantLock 原理分析JavaReentrantLock
- 淺談Java中的鎖:Synchronized、重入鎖、讀寫鎖Javasynchronized
- Golang可重入鎖的實現Golang
- Lock鎖之重入鎖與讀寫鎖
- 重入鎖的理解
- ZooKeeper 分散式鎖 Curator 原始碼 01:可重入鎖分散式原始碼
- java高併發系列 - 第12天JUC:ReentrantLock重入鎖JavaReentrantLock
- ReentrantLock可重入鎖——原始碼詳解ReentrantLock原始碼
- ReentrantLock可重入鎖、公平鎖非公平鎖區別與實現原理ReentrantLock
- synchronized鎖重入問題synchronized
- Java併發(十六)----執行緒八鎖Java執行緒
- Java併發包原始碼學習系列:ReentrantLock可重入獨佔鎖詳解Java原始碼ReentrantLock
- Lock介面、重入鎖ReentrantLock、讀寫鎖ReentrantReadWriteLockReentrantLock
- Redis實現可重入的分散式鎖Redis分散式
- Go 為什麼不支援可重入鎖?Go
- 多執行緒的這些鎖知道嗎?手寫一個自旋鎖?執行緒
- ZooKeeper 分散式鎖 Curator 原始碼 02:可重入鎖重複加鎖和鎖釋放分散式原始碼
- 多執行緒與併發----讀寫鎖執行緒
- Java多執行緒 -- 公平鎖和非公平鎖Java執行緒
- Java多執行緒(2)執行緒鎖Java執行緒