多线程学习----读写锁的使用(十二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/havebeenstand/article/details/83616162

读写锁

     读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁和写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但是不能同时写,那就让读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!

读写锁的应用:

假设开启三个线程写数据,三个线程读数据(读读不互斥,读写互斥,写写互斥)

public class ReadWriteLockStudy {

	
	public static void main(String[] args) {
		ReadAndWrite raw = new ReadAndWrite();
		for(int i = 0;i < 3;i++){
			new Thread(new Runnable() {
				@Override
				public void run() {
					raw.get();//读
				}
			}).start();
			new Thread(new Runnable() {
				@Override
				public void run() {
					raw.set(Math.random()*1000);//写
				}
			}).start();
		}
	}
	
}
class ReadAndWrite{
	private Object data = null;
	ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	public void get(){
		readWriteLock.readLock().lock();;
		System.out.println(Thread.currentThread().getName()+" be ready to read");
		try {
			Thread.sleep((long)Math.random()*1000);
			System.out.println(Thread.currentThread().getName()+" has read data:"+data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			readWriteLock.readLock().unlock();
		}
		
	}
	public void set(Object data){
		readWriteLock.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName()+" be ready to write");
			Thread.sleep((long)Math.random()*1000);
			this.data = data;
			System.out.println(Thread.currentThread().getName()+" has write data:"+this.data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			readWriteLock.writeLock().unlock();
		}
		
	}
}

面试题:写一个缓存系统的伪代码

public class CacheDemoStudy {

	private  Map<String,Object> cache = new HashMap<String,Object>();
	public static void main(String[] args) {
		final CacheDemoStudy cacheDemoStudy = new CacheDemoStudy();
		for(int i = 0;i < 5;i++){
			new Thread(new Runnable() {
				@Override
				public void run() {
						System.out.println(Thread.currentThread().getName()+"拿到数据"+cacheDemoStudy.getData("dataKey"));
				}
			}).start();
		}
	}
	
	private ReadWriteLock rwl = new ReentrantReadWriteLock();
	public  Object getData(String key){
		rwl.readLock().lock();
		try{
			System.out.println(Thread.currentThread().getName()+"去拿数据");
			if(cache.get(key) == null){
				System.out.println(Thread.currentThread().getName()+"没有拿到数据");
			}
			if(cache.get(key) == null){
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				try{
					if(cache.get(key) == null){
						System.out.println(Thread.currentThread().getName()+"去写数据");
						cache.put("dataKey", "aaaaa");
					}
				}finally{
					rwl.writeLock().unlock();
				}
				rwl.readLock().lock();
			}
		}finally {
			rwl.readLock().unlock();
		}
		return cache.get(key);
	}
}

执行结果:

只去写了一次数据

猜你喜欢

转载自blog.csdn.net/havebeenstand/article/details/83616162