Java中的鎖是用來解決多線程情況下的并發訪問問題,它可以控制對公共資源的訪問權,保證在同一時刻只有一個線程對該資源進行操作。根據鎖的特點和使用場景不同,Java的鎖可以分為如下幾種:
1. synchronized鎖
在Java中,synchronized是最簡單的一種鎖。當一個線程想要執行 synchronized 所控制的代碼時,它必須先獲得鎖,如果鎖已被其他線程占用,則該線程將處于等待狀態,直到其他線程釋放了鎖。synchronized鎖可用于實現互斥鎖。
public synchronized void synchronizedMethod() {
// synchronized代碼塊
}
2. ReentrantLock鎖
ReentrantLock是Java自帶的一個可重入鎖,它提供了許多附加的功能,如公平鎖、讀寫鎖、可中斷的鎖等。相比synchronized,ReentrantLock更靈活、功能更豐富。
ReentrantLock lock = new ReentrantLock();
public void reentrantlockMethod() {
lock.lock(); // 獲取鎖
try {
// ReentrantLock代碼塊
} finally {
lock.unlock(); // 釋放鎖
}
}
3. ReadWriteLock鎖
ReadWriteLock是Java自帶的讀寫鎖,它允許多個線程同時讀取一個共享資源,但對于寫操作,同一時間只能有一個線程操作,寫操作是獨占的。
ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void readWriteLockMethod() {
rwLock.readLock().lock(); // 獲取讀鎖
try {
// 讀操作代碼塊
} finally {
rwLock.readLock().unlock(); // 釋放讀鎖
}
rwLock.writeLock().lock(); // 獲取寫鎖
try {
// 寫操作代碼塊
} finally {
rwLock.writeLock().unlock(); // 釋放寫鎖
}
}
Java鎖狀態
Java中的鎖可以處于如下幾種狀態:
- 無鎖狀態:線程可以直接訪問對象。
- 偏向鎖狀態:某個線程占有鎖后,再次進入同步塊時無需競爭鎖,直接進入。
- 輕量級鎖狀態:當線程間沒有發生競爭時,使用CAS操作把對象頭轉為指向線程棧中的鎖記錄。
- 重量級鎖狀態:當線程間發生競爭時,輕量級鎖升級為重量級鎖,線程被掛起并進入鎖等待隊列。
各種鎖的狀態轉化會涉及Java底層的一些機制,如對象頭、CAS、線程棧、等待隊列等,了解這些機制可以更好地理解Java中鎖的原理及其使用。