第六章 Read-Write Lock(适合读取比写入次数频繁的时候)

本文详细介绍了读写锁的工作原理及其实现方式。通过自定义的ReadWriteLock类,阐述了如何在多线程环境中实现数据的安全读写操作,特别是在生产者-消费者模式下如何有效地平衡读写操作的竞争。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景介绍:将读取与写入分开来处理,在读取数据之前,必须获取用来读取的锁定。而要写入的时候,则必须获取用来写入的锁定。

Example:在生产-消费基础上,加入ReadWriteLock, lock.readLock()  -> lock.writeLock()

                                                                                                   doRead()            -> doWrite(c)

                                                                                                   lock.readUnLock()  -> lock.writeUnLock()



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 {1
          waitingWriters--;                   // (B)正在等待写入的线程数量减1
        }
        writingWriters++;                       //  (C)实际正在写入的线程数量加1
    }

    public synchronized void writeUnlock() {
        writingWriters--;                       // (C)实际正在写入的线程数量减
        preferWriter = false;
        notifyAll();
    }
}

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 < 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[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) {
        }
    }
}

//性能弱于前者
public class Data {
    private final char[] buffer;
    public Data(int size) {
        this.buffer = new char[size];
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = '*';
        }
    }
    public synchronized char[] read() throws InterruptedException {
        return doRead();
    }
    public synchronized void write(char c) throws InterruptedException {
        doWrite(c);
    }
    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) {
        }
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值