Read-Write Lock
Read-Write Lock模式介绍
在Read-Write Lock模式中,读取操作和写入操作是分开考虑的。在执行写操作时,线程必须获取用于写入的锁;在执行读操作时,线程需要获取用于读的锁;
Read-Write Lock使用场景
- 多线程环境下同一对象进行访问操作,有的访问操作会改变对象的状态,有的则不会;可以利用执行读取操作的线程之间不会发生冲突的特性来提高性能;
- 适合读取操作频率高于写入操作频率的场景;
- 适合读取操作较为繁重时,此时如果限制单线程执行(也就是Single Threaded Execution),则对系统影响较大;
Read-Write Lock示例代码分析
//多线程访问安全的数据类
public class Data {
private final char[] buffer;
private final ReadWriteLock lock=new ReadWriteLock();
public Data(int size){
this.buffer=new char[size];
for(int i=0;i<size;i++){
buffer[i]='*';
}
}
public char[] read()throws InterruptedException{
lock.readLock();
try{
return doRead();
}finally{
lock.readUnlock();
}
}
public void write(char c)throws InterruptedException{
lock.writeLock();
try{
doWrite(c);
}finally{
lock.writeUnlock();
}
}
private char[] doRead(){
char[] newBuf=new char[buffer.length];
for(int i=0;i<buffer.length;i++){
newBuf[i]=buffer[i];
}
slowly();
return newBuf;
}
private void doWrite(char c){
for(int i=0;i<buffer.length;i++){
buffer[i]=c;
slowly();
}
}
private void slowly(){
try{
Thread.sleep(50);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//读写锁
public class ReadWriteLock {
private int readingReaders=0;
private int waitingWriters=0;
private int writingWriters=0;
private boolean preferWriter=true;
public synchronized void readLock() throws InterruptedException{
while(writingWriters>0||(preferWriter&&waitingWriters>0)){
wait();
}
readingReaders++;
}
public synchronized void readUnlock(){
readingReaders--;
preferWriter=true;
notifyAll();
}
public synchronized void writeLock()throws InterruptedException{
waitingWriters++;
try{
while(readingReaders>0||writingWriters>0){
wait();
}
}finally{
waitingWriters--;
}
writingWriters++;
}
public synchronized void writeUnlock(){
writingWriters--;
preferWriter=false;
notifyAll();
}
}
//执行读Data操作的线程
public class ReaderThread extends Thread{
private final Data data;
public ReaderThread(Data data){
this.data=data;
}
public void run(){
try{
while(true){
char[] readBuf=data.read();
System.out.println(Thread.currentThread().getName()+" reads "+String.valueOf(readBuf));
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//执行写Data操作的线程
public class WriterThread extends Thread {
private static final Random random=new Random();
private final Data data;
private final String filler;
private int index=0;
public WriterThread(Data data,String filler){
this.data=data;
this.filler=filler;
}
public void run(){
try{
while(true){
char c=nextChar();
data.write(c);
Thread.sleep(random.nextInt(3000));
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
private char nextChar(){
char c=filler.charAt(index);
index++;
if(index>=filler.length()){
index=0;
}
return c;
}
}
//启动类
public class Tester {
public static void main(String[] args){
Data data=new Data(10);
new ReaderThread(data).start();
new ReaderThread(data).start();
new ReaderThread(data).start();
new ReaderThread(data).start();
new ReaderThread(data).start();
new WriterThread(data,"ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
new WriterThread(data,"abcdefghijklmnopqrstuvwxyz").start();
}
}
Read-Write Lock模式的理解
Read-Write Lock模式实际上是对多线程下对资源的访问进行了分类,从而得到两种逻辑锁;对多个不会改变对象状态的“读”线程,并不执行互斥,从而消除了执行互斥处理所带来的性能损耗;