ReadWriteLock用法
物件的方法中一旦加入synchronized修飾,則任何時刻只能有一個執行緒訪問synchronized修飾的方法。假設有個資料物件擁有寫方法與讀方法,多執行緒環境中要想保證資料的安全,需對該物件的讀寫方法都要加入 synchronized同步塊。這樣任何執行緒在寫入時,其它執行緒無法讀取與改變資料;如果有執行緒在讀取時,其他執行緒也無法讀取或寫入。這種方式在寫入操作遠大於讀操作時,問題不大,而當讀取遠遠大於寫入時,會造成效能瓶頸,因為此種情況下讀取操作是可以同時進行的,而加鎖操作限制了資料的併發讀取。
ReadWriteLock解決了這個問題,當寫操作時,其他執行緒無法讀取或寫入資料,而當讀操作時,其它執行緒無法寫入資料,但卻可以讀取資料 。
且看 以下例子
public class ReadWriteLockDemo {
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
Data data = new Data();
Worker t1 = new Worker(data,true);
Worker t2 = new Worker(data,true);
t1.start();
t2.start();
}
static class Worker extends Thread {
Data data;
boolean read;
public Worker(Data data, boolean read) {
this.data = data;
this.read = read;
}
public void run() {
if (read)
data.get();
else
data.set();
}
}
static class Data {
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock read = lock.readLock();
Lock write = lock.writeLock();
public void set() {
write.lock();
System.out.println(Thread.currentThread().hashCode()
+ " set:begin " + sdf.format(new Date()));
try {
Thread.sleep(5000);
//
} catch (Exception e) {
} finally {
System.out.println(Thread.currentThread().hashCode() + " set:end "
+ sdf.format(new Date()));
write.unlock();
}
}
public int get() {
read.lock();
System.out.println(Thread.currentThread().hashCode()
+ " get :begin " + sdf.format(new Date()));
try {
Thread.sleep(5000);
//
} catch (Exception e) {
} finally {
System.out.println(Thread.currentThread().hashCode() + " get :end "
+ sdf.format(new Date()));
read.unlock();
}
return 1;
}
}
}
兩個執行緒均是讀執行緒,結果如下
22474382 get :begin 2011-04-16 18:26:13
4699264 get :begin 2011-04-16 18:26:13
22474382 get :end 2011-04-16 18:26:18
4699264 get :end 2011-04-16 18:26:18
兩讀執行緒均可同時讀取資料,下面看一個是讀執行緒,一個寫執行緒的情況
Data data = new Data();
Worker t1 = new Worker(data,false);
Worker t2 = new Worker(data,true);
t2.start();
Thread.sleep(100);
t1.start();
先啟動讀取執行緒,再啟動寫入執行緒,看結果
14718739 get :begin 2011-04-16 18:54:46
14718739 get :end 2011-04-16 18:54:51
14737862 set:begin 2011-04-16 18:54:51
14737862 set:end 2011-04-16 18:54:56
可以看到讀取執行緒工作時,寫入執行緒是不能訪問資料的
相關文章
- Java讀寫鎖ReadWriteLockJava
- 鎖——Lock、Condition、ReadWriteLock、LockSupport
- ReadWriteLock與ReentrantReadWriteLock
- 高併發之Phaser、ReadWriteLock、StampedLock
- Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解Java
- StampedLock:JDK1.8中新增,比ReadWriteLock還快的鎖JDK
- 【高併發】ReadWriteLock怎麼和快取扯上關係了?!快取
- Java多執行緒/併發06、執行緒鎖Lock與ReadWriteLockJava執行緒
- ReadWriteLock讀寫鎖升級的踩坑:Kotlin作弊,最好使用StampedLock - javaspecialistsKotlinJava
- with用法
- Qdrant用法;Qdrant在langchain裡的用法LangChain
- 併發王者課-鉑金2:豁然開朗-“晦澀難懂”的ReadWriteLock竟如此妙不可言
- sessionStorage 用法Session
- WebSocket 用法Web
- SQLserver With As 用法SQLServer
- requestAnimationFrame用法requestAnimationFrame
- requestAnimationFrame()用法requestAnimationFrame
- JavaScript this用法JavaScript
- quilt用法UI
- WITH AS 用法-CTE
- ORACLE WITH AS 用法Oracle
- dvbsnoop用法OOP
- ioctlsocket() 用法TLS
- enum用法
- seqkit用法
- GPG 用法
- typedef用法
- union用法
- JavaScript用法JavaScript
- JOptionPane用法
- Yii2-application用法 (Yii::$app用法)APP
- 原來ReadWriteLock也能開發高效能快取,看完我也能和麵試官好好聊聊了!快取
- SQL AS 的用法SQL
- rsync 用法教程
- SUBMIT 的用法MIT
- Vue 元件用法Vue元件
- Promise基本用法Promise
- indexOf()的用法Index