Read-Write Lock模式

Read-Write Lock 模式

0. 描述了什么事?

使用一个人来专门控制锁。

1. 类的说明,怎么抽象?

类名 说明
Main 启动类
ReadWriteLock 读写锁类,该类提供了用于读取和写入的锁
Data 数据的抽象类,保存 ReadWriteLock 的实例
ReaderThread 保存 Data 的实例,并不断读取其内容
WriterThread 保存 Data 的实例,并不断更新其内容

2. 程序示例

1. Main.java

package read.write.lock;

public class Main {
    public static void main(String[] args) {
        Data data = new Data(10);
        for (int i = 0; i < 6; i++) {
            new ReaderThread(data).start();
        }
        new WriterThread(data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
        new WriterThread(data, "abcdefghijklmnopqrstuvwxyz").start();
    }
}

2. ReadWriteLock.java

package read.write.lock;

public class ReadWriteLock {
    private int readingReaders = 0;
    private int writingWriters = 0;
    private int waitingWriters = 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 (writingWriters > 0 || readingReaders > 0) {
                wait();
            }
        } finally {
            // 不管写成功没有,都必须把等待线程给从等待队列中去除掉
            waitingWriters--;
        }
        // 开始写了!
        writingWriters++;
    }

    public synchronized void writeUnlock() {
        // 释放掉写入锁,并且唤醒其他的写入锁和读取锁
        writingWriters--;
        preferWriter = false;
        notifyAll();
    }
}

3. ReaderThread.java

package read.write.lock;

public class ReaderThread extends Thread {
    private final Data data;

    public ReaderThread(Data data) {
        this.data = data;
    }

    @Override
    public void run() {
        try {
            while (true) {
                char[] buffer = data.read();
                System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(buffer));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4. WriterThread.java

package read.write.lock;

import java.util.Random;

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;
    }

    @Override
    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 = (++index) % filler.length();
        return c;
    }
}

你可能感兴趣的:(Read-Write Lock模式)