读写锁ReadWriteLock和缓存实例

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

读写锁:多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。即:读的时候不允许写,写的时候不允许读,可以同时读。

synchronized关键字和普通的Lock构造的锁,会造成读与读之间的互斥,因此读写锁可提高性能。

例子1:三个线程同时对一个共享数据进行读写。

importjava.util.Random;

importjava.util.concurrent.locks.ReadWriteLock;

importjava.util.concurrent.locks.ReentrantReadWriteLock;

publicclassReadWriteLockTest {

publicstaticvoidmain(String[] args) {

finalQueue queue =newQueue();

for(inti = 0; i < 3; i++) {

newThread() {

publicvoidrun() {

while(true) {

queue.get();

}

}

}.start();

newThread() {

publicvoidrun() {

while(true) {

queue.put(newRandom().nextInt(10000));

}

}

}.start();

}

}

}

classQueue {

PRivateObjectdata=null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。

ReadWriteLockrwl=newReentrantReadWriteLock();

publicvoidget() {

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();

}

}

publicvoidput(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();

}

}

}

例子2:缓存实例

importjava.util.HashMap;

importjava.util.Map;

importjava.util.concurrent.locks.ReadWriteLock;

importjava.util.concurrent.locks.ReentrantReadWriteLock;

publicclassCacheDemo {

privatestaticMap<String, Object>cache=newHashMap<String, Object>();

privateReadWriteLockrwl=newReentrantReadWriteLock();

publicObject getData(String key) {

// 当线程开始读时,首先开始加上读锁

rwl.readLock().lock();

Object value =null;

try{

value =cache.get(key);

// 判断是否存在值

if(value ==null) {

// 在开始写之前,首先要释放读锁,否则写锁无法拿到

rwl.readLock().unlock();

// 获取写锁开始写数据

rwl.writeLock().lock();

try{

// 再次判断该值是否为空,因为如果两个写线程都阻塞在这里,

// 当一个线程被唤醒后value的值为null则进行数据加载,当另外一个线程也被唤醒如果不判断就会执行两次写

if(value ==null) {

value ="";// query数据库

cache.put(key, value);

}

}finally{

rwl.writeLock().unlock();// 释放写锁

}

rwl.readLock().lock();// 写完之后降级为读锁

}

}finally{

rwl.readLock().unlock();// 释放读锁

}

returnvalue;

}

}

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航