JAVA 并发编程-读写锁之模拟缓存系统
Posted blfbuaa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 并发编程-读写锁之模拟缓存系统相关的知识,希望对你有一定的参考价值。
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保证别的线程不会看到数据不完整的文件。这时候就须要使用读写锁。
/** * 简单读写锁demo * @author hejingyuan * */ public class ReadWriteLockTest { public static void main(String[] args) { final Queue3 q3 = new Queue3(); //创建几个线程 for(int i=0;i<3;i++) { new Thread(){ public void run(){ while(true){ q3.get(); } } }.start(); new Thread(){ public void run(){ while(true){ q3.put(new Random().nextInt(10000)); } } }.start(); } } } class Queue3{ private Object data = null;//共享数据。仅仅能有一个线程能写该数据,但能够有多个线程同一时候读该数据 //读写锁 ReadWriteLock rwl = new ReentrantReadWriteLock(); //读数据 public void get(){ rwl.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to read data!"); Thread.sleep((long)(Math.random()*1000)); System.out.println(Thread.currentThread().getName() + "have read data :" + data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.readLock().unlock(); } } //写数据 public void put(Object data){ rwl.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to write data!"); Thread.sleep((long)(Math.random()*1000)); this.data = data; System.out.println(Thread.currentThread().getName() + " have write data: " + data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.writeLock().unlock(); } } }
运行结果:
Thread-0 be ready to readdata!
Thread-2 be ready to readdata!
Thread-2have read data:null
Thread-0have read data:null
Thread-1 be ready towrite data!
Thread-1 have write data:1021
Thread-1 be ready towrite data!
Thread-1 have write data:2887
看到这里不免有人会问。既然读的时候能够多人訪问。那么为什么还要加读锁呢?
答:当然要加锁了,否则在写时去读,可能不对-(写的时候不能去读)
读写锁-模拟缓存系统实现:
public class CacheDemo { private Map<String, Object> cache = new HashMap<String, Object>(); public static void main(String[] args) { } //定义读写锁 private ReadWriteLock rwl = new ReentrantReadWriteLock(); //读数据。使用读锁 public Object getData(String key){ //加入读锁 rwl.readLock().lock(); Object value = null; try{ value = cache.get(key); if(value == null){ //释放读锁 rwl.readLock().unlock(); //加上写锁 rwl.writeLock().lock(); try{ //如果三个线程同一时候去获取写锁,我们知道仅仅有第一个线程能够获取 //那么其它两个线程仅仅有等了,如果第一个线程按流程运行完后,刚才的两个线程能够得到写锁了, //然后接着就能够改动数据了(赋值).所以加上推断! if(value==null){//为什么还要推断? value = "aaaa";//实际是去queryDB(); } }finally{ //释放写锁 rwl.writeLock().unlock(); } rwl.readLock().lock(); } }finally{ rwl.readLock().unlock(); } return value; } }
总结:
读写锁的作用为,当我们加上写锁时,其它线程被堵塞,仅仅有一个写操作在运行,当我们加上读锁后,它是不会限制多个读线程去訪问的。也就是get和put之间是相互排斥的。put与不论什么线程均为相互排斥。可是get与get线程间并非相互排斥的。事实上加读写锁的目的是同一把锁的读锁既能够与写锁相互排斥,读锁之间还能够共享。
以上是关于JAVA 并发编程-读写锁之模拟缓存系统的主要内容,如果未能解决你的问题,请参考以下文章