一、釋放鎖
1.void unlock()方法
嘗試釋放鎖,如果當前執行緒持有鎖,則呼叫該方法會讓該執行緒對該執行緒持有的AQS狀態值減1,如果減去1后當前狀態值為0,則當前執行緒會釋放該鎖,否則僅僅減去1而已,如果當前執行緒沒有持有該鎖而呼叫了該方法就會拋出IllegalMonitorStateException例外,代碼如下
public void unlock() {
sync.release();
}
public final boolean tryRelease( int releases) {
// 如果不是鎖持有者,則呼叫 unlock則拋出例外
int c = getState() - releases;
if(Thread.currentThread() != getExclusiveOwnerThread()) {
throw new IllegalMonitorStateException();
}
boolean free = false;
// 如果當前可重入的次數為0,則清空鎖持有執行緒
if(c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
// 設定可重入次數為原始值-1
setState(c);
return free;
}
如上述代碼,如果當前執行緒不是該鎖的持有者則直接拋出例外,否則查看狀態值是否為0,為0則說明當前執行緒要放棄對該鎖的持有權,則執行代碼把當前鎖的持有者設定為null,如果狀態值不為0,則僅僅讓當前執行緒對該鎖的可重入次數減1.
2.下面以一個案例作為講解
package com.ruigege.LockSourceAnalysis6;
import java.util.ArrayList;
public static class ReentrantLockList {
//執行緒不安全的List
private ArrayList<String> array = new ArrayList<String>();
//獨占鎖
private volatile ReentrantLock lock = new ReentrantLock();
//添加元素
public void add(String e) {
lock.lock();
try {
array.add(e);
}finally {
lcok.unlock();
}
}
//洗掉元素
public void remove(String e) {
lock.lock();
try {
array.remove(e);
}finally {
lock.unlock();
}
}
//獲取資料
public String get(int index) {
lock.lock();
try {
return array.get(index);
}finally {
lock.unlock();
}
}
}
上述代碼實作了一個執行緒不安全的array,當一個執行緒獲取到鎖的時候,進行一系列的增刪改查,如果有其他執行緒想要獲取到該鎖,那么就會被放到AQS的佇列中,等待第一個執行緒釋放鎖,來供它們獲取,
二、讀寫鎖ReentrantReadWriteLock的原理
解決執行緒安全問題只需要ReentrantLock即可,但是大多數情況下,該鎖是獨占鎖,某時只有一個執行緒可以獲取到該鎖,那么實際上大多情況是寫少讀多,顯然這個場景是無法滿足的,所以ReentrantReadWriteLock就應運而生了,ReentrantReadWriteLock采用的時讀寫分離的策略,可以允許多個執行緒同時獲取鎖, 我們下次再來決議這個類
三、原始碼:
所在包:com.ruigege.ConcurrentListSouceCodeAnalysis5 https://github.com/ruigege66/ConcurrentJavaCSDN:https://blog.csdn.net/weixin_44630050 博客園:https://www.cnblogs.com/ruigege0000/ 歡迎關注微信公眾號:傅里葉變換,個人賬號,僅用于技術交流 
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/276578.html
標籤:其他
下一篇:Set和Map
