1. 讀寫鎖機制——ReadWriteLock接口
讀寫鎖適用於對數據結構頻繁讀而較少修改的場景。舉個栗子,你可以創建一個在線詞典供多條讀線程併發讀取,然而單條寫線程可能會不時添加新的定義或更新已有的定義。一個資源可以被多個線程同時讀,或者被一個線程寫,但是不能同時存在讀和寫線程。
基本規則: 讀讀不互斥 、讀寫互斥 、寫寫互斥。
問:既然讀讀不互斥,爲什麼還要加讀鎖?
答:如果讀可以不是最新數據,也不需要加鎖。要保證讀取數據的嚴格實時性,就必須加讀寫鎖。
2. ReadWriteLock接口聲明的方法
(1)Lock readLock():返回用於讀的鎖。
(2)Lock writeLock():返回用於寫的鎖。
3. ReadWriteLock接口的實現類——重入讀寫鎖ReentrantReadWriteLock
常用方法
方法名稱 | 描述 |
ReentrantReadWriteLock() | 創建一個重入讀寫鎖的實例。 |
ReentrantReadWriteLock(boolean fair) | 創建一個具有公平策略的重入讀寫鎖實例。 |
ReadLock readLock() | 返回用於讀的鎖。 |
WriteLock writeLock() | 返回用於寫的鎖。 |
int getReadHoldCount() | 返回被調用線程在這個鎖上持有讀鎖的數量,當調用線程沒有持有這個讀鎖,返回0. |
int getWriteHoldCount() | 返回被調用線程在這個鎖上持有寫鎖的數量,當調用線程沒有持有這個寫鎖,返回0. |
4. 示例
寫線程產生單詞定義的條目,而讀線程持續隨機地訪問這些條目並打印出來。
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReentrantReadWriteLockDemo {
public static void main(String[] args)
{
final String[] words = {"dog","cat","bird","fish","human"};
final String[] definitions = {"a member of the genus Canis",
"feline mammal usually having thick soft fur ",
"A bird is a feathered, winged, bipedal, warm-blooded, egg-laying, vertebrate animal.",
"Fish are vertebrates with gills that live in water",
"characterized by superior intelligence, articulate speech, and erect carriage"};
final Map<String,String> dictionary = new HashMap<String,String>();
ReadWriteLock rwlock = new ReentrantReadWriteLock();
final Lock rlock = rwlock.readLock();
final Lock wlock = rwlock.writeLock();
Runnable writer = ()->
{
for(int i = 0; i < words.length; i++)
{
wlock.lock();
dictionary.put(words[i], definitions[i]);
System.out.println("寫入單詞:"+words[i]);
wlock.unlock();
try {
Thread.sleep(100); //讓其他線程有機會運行
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
ExecutorService es = Executors.newFixedThreadPool(1);
es.submit(writer);
Runnable reader = ()->
{
while(true)
{
rlock.lock();
int i = (int) (Math.random() * words.length); //隨機讀取一個單詞
System.out.println("讀取單詞:"+words[i]+",它的意思是:" + dictionary.get(words[i]));
rlock.unlock();
}
};
es = Executors.newFixedThreadPool(1);
es.submit(reader);
}
}
運行結果:
讀取單詞:human,它的意思是:characterized by superior intelligence, articulate speech, and erect carriage
讀取單詞:cat,它的意思是:feline mammal usually having thick soft fur
讀取單詞:fish,它的意思是:Fish are vertebrates with gills that live in water
讀取單詞:dog,它的意思是:a member of the genus Canis
讀取單詞:fish,它的意思是:Fish are vertebrates with gills that live in water
讀取單詞:cat,它的意思是:feline mammal usually having thick soft fur
讀取單詞:fish,它的意思是:Fish are vertebrates with gills that live in water
讀取單詞:cat,它的意思是:feline mammal usually having thick soft fur........