美文网首页
Java多线程Read-Write-Lock模式

Java多线程Read-Write-Lock模式

作者: aimountain | 来源:发表于2018-11-12 11:45 被阅读0次

概述

大家一起读没问题,但是读的时候不要写哦。黑板上写满了板书,老师刚想擦,同学们说道:“老师,我们还没看完呢,请先不要擦掉!”。

示例程序

类一览表
Main   测试程序行为的类
Data   可以读写的类
WriterThread     表示写入线程的类
ReaderThread   表示读取线程的类
ReadWriteLock  表示读写锁的类
Main 类
public class Main {
  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 ReaderThread(data).start();
    new WriterThread(data, "ABCDEF").start();
    new WriterThread(data, "abcdef").start();


  }
}
Data 类
Data类是可以执行读取(read)和写入(write)操作的类。
buffer字段是实际的读写对象char的数组。
lock字段保存的是该模式的主角ReadWriteLock的实例。
public class Data {
  private final char[] buffer;
  private final ReadWriteLcok lock = new ReadWriteLock();
  public Data(int size) {
    this.buffer = new char[size];
    for(int i = 0; i < buffer.length; 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 = 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){}
  }
}
WriterThread 类
import java.util.Random;


public class WriterThread extends Thread {
  private static final Random random = new Random();
  private final Data data;
  private final String filter;
  private int index = 0;
  public WriterThread(Data data, String filter) {
    this.data = data;
    this.filter = filter;
  }
    
  public void run() {
    try{
      while(true){
        char c = nextchar();
        data.write(c);
        Thread.sleep(random.nextInt(3000));
       }
    } catch (InterruptedException e){}
  }

  private char nextchar(){
    char  c = filter.charAt(index);
    index++;
    if(index >= filter.length()) {
      index = 0;
    }
    return c;
  }
} 
ReadWriteLock 类
public final class ReadWriteLock {
  private int readingReaders = 0;    //(A)实际正在读取中的线程数
  private int waitingWriters = 0;       //(B)正在等待写入的线程个数
  private int writingWriters = 0;        //(C)实际正在写入中的线程个数
  private boolean preferWriter = true;  /若写入优先,则为true

  public synchronized void readLock() throws InterruptedException {
    while( writingWriters > 0 || ( preferWriter && waitingWriters > 0)){
      wait();
    }
    readingReaders++;         //(A) 实际正在读取的线程个数加1
  }

  public synchronized void readUnlock() {
    readingReaders--;       //(A)实际正在读取的线程个数减1
    preferWriter = true;
    notifyAll();
  }

  public synchronized void writeLock() throws InterruptedException {
    waitingWriters++;        //(B)正在等待写入的线程个数加1
    try {
      while ( readingReaders > 0 || writingWriters > 0) {
        wait();
      }
    } finally {
      waitingWriters--;    //(B)正在等待写入的线程个数减1
    }
    writingWriters++;    //(C)实际在这写入的线程个数加1
  }

  public synchronized void writeUnlock() {
    writingWriters--;
    preferWriter = false;
    notifyAll();
  }
}

守护条件确认

ReadWriteLock类中readLock方法和writeLock方法都使用了Guarded Suspension模式。

  • readLock方法
    守护条件是“没有线程正在执行写入操作”。
  • writeLock方法
    守护条件是“没有线程正在执行读取操作或写入操作”。

Read-Write Lock 模式中的登场角色

  • Reader(读者)
    Reader角色对SharedResource角色执行read操作。在示例程序中,由ReaderThread类扮演。
  • Writer(写者)
    Writer角色对SharedResource角色执行write操作。在示例程序中,由WriterThread类扮演。
  • SharedResource(共享资源)
    SharedResource角色表示的是Reader角色和Writer角色二者共享的资源。在示例程序中,由Data类扮演。
  • ReadWriteLock(读写锁)
    ReadWriteLock角色提供了read操作和write操作时所需的锁。即实现read操作时所需的readLock和readUnlock,以及实现write操作时所需要的writeLock和writeUnlock。在示例程序中,由ReadWriteLock类扮演。

相关文章

网友评论

      本文标题:Java多线程Read-Write-Lock模式

      本文链接:https://www.haomeiwen.com/subject/dkpwtqtx.html