多线程之读写锁模式 Read-Write Lock Pattern

场景:
老师在黑板上写了字,很多学生在下面读
现在老师要擦掉重写,学生们说我们还没看完呢 等我们全部看完了才能擦
这就是读写锁:没有线程读取时才能写入

看程序如何实现吧
看以看到一次完整的读取或者写入要获取两次锁,这也就是加大了读写锁的使用成本
所以读写锁用来处理一些比较耗时的计算更划算

public class ReadWriteLock {
	
	private int readerCount = 0; //读取线程数
	private int writerCount = 0; //写入线程数
	
	/**
	 * 获取读锁时:
	 * 已经有线程在读取 ---获取成功
	 * 已经有线程在写入---等待
	 * 
	 * @throws InterruptedException
	 */
	public synchronized void readLock() throws InterruptedException{
		while(writerCount > 0){ //线程正在写  
			wait();  //读取线程等待
		}
			
		readerCount++;   //获取读锁成功
	}
	
	/**
	 * 释放读锁
	 */
	public synchronized void readUnlock(){
			readerCount--;
			notifyAll();
	}
	
	/**
	 * 获取写锁:
	 * 读取线程大于0 -- 等待
	 * 写入线程大于0 -- 等待
	 * 
	 * @throws InterruptedException
	 */
	public synchronized void writeLock() throws InterruptedException{
		while (readerCount > 0 || writerCount > 0) {
			wait();
		}
		
		writerCount++;
	}
	
	public synchronized void writeUnlock() throws InterruptedException{
		writerCount--;
		notifyAll();
	}
}

package com.justel.fs.rwlock;

/**
 * 
 * @author 徐良永
 * @date 2013-6-8下午4:36:22
 */
public class ReaderThread extends Thread {

	private Data data;
	
	public ReaderThread(Data data){
		this.data = data;
	}
	
	public void run(){
		try {
			for (int i = 0; i < 100; i++) {
				System.out.println(Thread.currentThread().getName()+" "+data.read());
				Thread.sleep(600);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
package com.justel.fs.rwlock;

/**
 * 
 * @author 徐良永
 * @date 2013-6-8下午4:36:17
 */
public class WriterThread extends Thread {

	private Data data;
	
	public WriterThread(Data data){
		this.data = data;
	}
	
	public void run(){
		try {
			for (int i = 0; i < 100; i++) {
				data.write("Content:" + i);
				System.out.println("Write content:" + i);
				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
package com.justel.fs.rwlock;

public class Data {
	private String content = "INIT";
	private ReadWriteLock readWriteLock = new ReadWriteLock();

	public String read() throws InterruptedException{
		readWriteLock.readLock();
		try {
			return content;
		} finally{
			readWriteLock.readUnlock();
		}
	}
	
	
	public void write(String s)throws InterruptedException{
		readWriteLock.writeLock();
		try {
			content = s;
		} finally{
			readWriteLock.writeUnlock();
		}
	}
	
	
}
package com.justel.fs.rwlock;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Data data = new Data();
		new WriterThread(data).start();
		
		new ReaderThread(data).start();
		new ReaderThread(data).start();
		new ReaderThread(data).start();
//		new ReaderThread(data).start();
//		new ReaderThread(data).start();
	}

}

你可能感兴趣的:(Pattern)