我是靠谱客的博主 老迟到外套,最近开发中收集的这篇文章主要介绍玩转并发-多线程读写锁分离设计模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

概述

在多线程的情况下访问共享资源,需要对资源进行同步操作以防止数据不同步的情况发生,通常我们用synchronized关键字或显氏锁。
对资源的访问一般包括两种类型的动作,读和写。如果多个线程在某个时刻对资源进行读操作,这时用排他的方式加锁,就显得简单粗暴,降低执行效率。如果的某个资源的读操作多于写操作,那么读时不加锁,很明显能很好地提升性能。


多线程访问concern和conflict

线程
不冲突冲突
冲突冲突

共享资源在多个线程中同时进行读操作不会引起冲突


ReadWriteLock

public class ReadWriteLock {
	//正在读的读线程
	private int readingReaders=0;
	//正在等待的读线程
	private int waitingReaders=0;
	//正在写的写进程
	private int writingWriters=0;
	//正在等待的写进程
	private int waitingWriters=0;
	//是否倾向写进程
	private static boolean preferWriter=true;
	
	public ReadWriteLock() {
		this(preferWriter);
	}
	
	public ReadWriteLock(boolean preferWriter) {
		this.preferWriter=preferWriter;
	}
	
	public synchronized void readLock() {
		this.waitingReaders++;
		try {
			//如果有正在写的写线程或者读写锁倾向写进程且有等待的写线程则wait
			while(writingWriters>0 ||(preferWriter && waitingWriters>0)) {
				this.wait();
			}
			this.readingReaders++;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			this.waitingReaders--;
		}
	}
	
	public synchronized void readUnlock() {
		this.readingReaders--;
		this.notifyAll();
	}
	
	public synchronized void writeLock() {
		this.waitingWriters++;
		try {
			//如果有正在读的线程或者正在写的写线程
			while(readingReaders>0 || writingWriters>0) {
				this.wait();
			}
			this.writingWriters++;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			this.waitingWriters--;
		}
	}
	
	public synchronized void writeUnlock() {
		this.writingWriters--;
		this.notifyAll();
	}
}

SharedResource

public class SharedResource {
	private final char[] buffer;
	
	private final ReadWriteLock lock =new ReadWriteLock();
	
	public SharedResource(int size) {
		this.buffer=new char[size];
		for(int i=0;i<size;i++) {
			buffer[i]='*';
		}
	}
	
	//读操作
	public char[] read() {
		try {
			lock.readLock();
			return this.doRead();
		}finally {
			lock.readUnlock();
		}
	}
	
	//写操作
	public void write(char data) {
		try {
			lock.writeLock();
			this.doWrite(data);
		}finally {
			lock.writeUnlock();
		}
	}
	
	//返回副本
	private char[] doRead() {
		char[] copyBuffer= new char[buffer.length];
		System.arraycopy(buffer, 0,copyBuffer,0,buffer.length);
		slowly(100);
		return copyBuffer;
	}
	
	
	private void doWrite(char data) {
		for(int i=0;i<buffer.length;i++) {
			buffer[i]=data;
		}
		slowly(50);
	}
	
	private void slowly(int ms) {
		try {
			Thread.sleep(ms);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}


ReadWorker

public class ReadWorker	extends Thread{
	private final SharedResource resource;

	public ReadWorker(SharedResource resource) {
		this.resource=resource;
	}

	@Override
	public void run() {
		char readBuf[];
		try {
			while(true) {
				readBuf=resource.read();
				System.out.println(Thread.currentThread().getName()+":"+String.valueOf(readBuf));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

WriteWorker

public class WriteWorker extends Thread{
	
	private final SharedResource resource;
	private static final Random random =new Random(System.currentTimeMillis());
	private final String string;
	private int index=0;
	
	public WriteWorker(SharedResource resource,String string) {
		this.resource=resource;
		this.string=string;
	}
	
	@Override
	public void run() {
		      try{
				while(true) {
					char c=nextchar();
					resource.write(c);
					Thread.sleep(random.nextInt(1000));	
				}
		      }
		      catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
	private char nextchar() {
		char c=string.charAt(index);
		index++;
		if(index>=string.length()) {
			index=0;
		}
		return c;
	}
}

测试类

public static void main(String[] args) {
		SharedResource sharedResource = new SharedResource(10);
		ReadWorker readWorker = new ReadWorker(sharedResource);
		WriteWorker writeWorker = new WriteWorker(sharedResource, "Reyco");
		readWorker.start();	
	}

最后

以上就是老迟到外套为你收集整理的玩转并发-多线程读写锁分离设计模式的全部内容,希望文章能够帮你解决玩转并发-多线程读写锁分离设计模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部