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........