Reader-Writer Pattern

本文详细介绍了读写锁的工作原理及其实现方式。通过具体的Java代码示例,展示了如何使用读写锁来优化多线程环境下对共享资源的访问效率。文章通过Reader和Writer两类线程的模拟运行,说明了读写锁如何确保数据的一致性和并发性。

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

当线程“读取”实例的状态时,实例的状态不会变化。会使实例状态变化的,只有线程对实例的“写入”的操作而已。如果把视角放在实例状态变化的角度来看时,“读取”与写入本身是不同的东西。
读写者问题解决的就是将实例的读取与写入分开来处理。在读取数据之前,必须获取用来读取的锁定,而要写入的时候,则必须获取用来写入的锁定。
因为进行读取时,实例的状态不会改变,所以,就算有多个线程在同时读取也没有关系。但,有线程在读取的时候,不可以做写入的操作。
写入的时候,实例的状态就会改变。于是,当有一个线程在写入的时候,其它线程就不可以有进行读取或写入。
一般来说,对实例的操作进行共享互斥会使程序性能变差,但将写入的共享互斥与读取的共享互斥分开来思考,就可以提升程序的性能。

Data 模拟可读写的实例

public class Data {

	private char[] buffer;

	private ReadWriteLock readWriteLock = new ReadWriteLock();

	public Data(int size) {
		buffer = new char[size];

		// 初始化缓冲区
		for (int i = 0; i < buffer.length; i++) {
			buffer[i] = '*';
		}
	}

	public char[] read() throws InterruptedException {
		readWriteLock.readLock();
		try {
			return doRead();
		} finally {
			readWriteLock.readUnLock();

		}
	}

	public void write(char ch) throws InterruptedException {
		readWriteLock.writeLock();
		try {
			doWrite(ch);
		} finally {
			readWriteLock.writeUnLock();
		}
	}

	private char[] doRead() throws InterruptedException {
		char[] chs = new char[buffer.length];

		Thread.sleep(500);
		
		for (int i = 0; i < buffer.length; i++) {
			chs[i] = buffer[i];
		}

		return chs;
	}

	private void doWrite(char ch) throws InterruptedException {
		Thread.sleep(1000);
		
		for (int i = 0; i < buffer.length; i++) {
			buffer[i] = ch;
		}
	}
}


ReadWriteLock 提供读写锁定的类

public class ReadWriteLock {

	private int readCount;

	private int writeCount;

	public ReadWriteLock() {
		readCount = 0;
		writeCount = 0;
	}

	public synchronized void readLock() throws InterruptedException {
		while (writeCount > 0) {
			wait();
		}

		readCount++;
	}

	public synchronized void readUnLock() {
		readCount--;

		notifyAll();
	}

	public synchronized void writeLock() throws InterruptedException {
		while (readCount > 0 || writeCount > 0) {
			wait();
		}

		writeCount++;
	}

	public synchronized void writeUnLock() throws InterruptedException {
		writeCount--;

		notifyAll();
	}
}


Reader 模拟读

public class Reader extends Thread {

	private Data data;

	public Reader(Data data,String threadName) {
		super(threadName);
		
		this.data = data;
	}

	@Override
	public void run() {
		while (true) {
			try {
				System.out.println(Thread.currentThread().getName() + "读取数据:"
						+ String.valueOf(data.read()));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}


Writer 模拟写

public class Writer extends Thread {

	private Data data;

	private char ch;// 要写入的字符(内容)

	public Writer(Data data, char ch, String threadName) {
		super(threadName);

		this.data = data;
		this.ch = ch;
	}

	@Override
	public void run() {
		while (true) {
			try {
				data.write(ch);

				System.out.println(Thread.currentThread().getName() + "写入数据:"
						+ ch);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}


Main 提供测试的类

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Data data = new Data(10);
		
		new Reader(data,"Reader1").start();
		new Reader(data,"Reader2").start();
		
		new Writer(data, 'A', "Writer1").start();
		new Writer(data, 'b', "Writer2").start();
		new Writer(data, 'C', "Writer3").start();
		
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值