java讀寫鎖
阿新 • • 發佈:2021-01-12
技術標籤:# 多執行緒
使用讀寫鎖要兼顧效能和安全性
對於共享資料來說,如果說某個方法在訪問它的時候,只是去讀取,並不更新資料,那是不是就不需要加鎖呢?還是需要的,因為如果一個執行緒讀資料的同時,另外一個執行緒同時在更新資料,那麼你讀到的資料有可能是更新到一半的資料,這肯定是不符合預期的。所以,無論是隻讀訪問,還是讀寫訪問,都是需要加鎖的。
如果給資料簡單地加一把鎖,雖然解決了安全性的問題,但是犧牲了效能,因為,那無論讀還是寫,都無法併發了,跟單執行緒的程式效能是一樣。
實際上,如果沒有執行緒在更新資料,那即使多個執行緒都在併發讀,也是沒有問題的。我在上節課跟你講過,大部分情況下,資料的讀寫比是不均衡的,讀要遠遠多於寫,所以,我們希望的是:
- 讀訪問可以併發執行。
- 寫的同時不能併發讀,也不能併發寫。
這樣就兼顧了效能和安全性。讀寫鎖就是為這一需求設計的。我們來看一下 Java 中提供的讀寫鎖:
ReadWriteLock rwlock = new ReentrantReadWriteLock();
public void read() {
rwlock.readLock().lock();
try {
// 在這兒讀取共享資料
} finally {
rwlock.readLock().unlock();
}
}
public void write() {
rwlock.writeLock().lock ();
try {
// 在這兒更新共享資料
} finally {
rwlock.writeLock().unlock();
}
}
在這段程式碼中,需要讀資料的時候,我們獲取讀鎖,獲取到的讀鎖不是一個互斥鎖,也就是說 read() 方法是可以多個執行緒並行執行的,這樣使得讀資料的效能依然很好。寫資料的時候,我們獲取寫鎖,當一個執行緒持有寫鎖的時候,其他執行緒既無法獲取讀鎖,也不能獲取寫鎖,達到保護共享資料的目的。
這樣,使用讀寫鎖就兼顧了效能和安全。