Java5并发库之锁(二)——读写锁技术的妙用
2013-04-23 17:01
330 查看
读写锁:读写锁分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由JVM自己控制的,我们只要上好相应的锁即可。如果代码是只读数据,可以很多人同时读,但不能同时写,那就需要上读锁;如果代码是修改数据,只能有一个人在写,且不能在写的时候读,就需要上写锁。总之,读的时候上读锁,写的时候上写锁。
1- 1 一个读写锁的例子
程序运行的结果:
从运行结果可以看到,当一个线程写的时候,其它的线程不允许写;而读的时候,允许多个线程同时读,且读到的数据是一致的。
在Hibernate中会有代码1-2 这样的代码:
代码1-2
代码1-3
那么代码1-2 与 1-3 有什么区别呢?
代码1-2 ,不管数据库中有没有记录,它都返回一个user对象,它是一个代理(是user的子类,可以被当做user用),是一个假的,不是一个真正的user对象。如下图:
代码1-3 ,是直接到数据库中把对象给“抓”出来,如果没有“抓”到,返回的值是NULL(空)。看看下面的这道面试题:
一个缓存系统(可以装很多的对象)的例子
注意代码
当其它的线程检查缓存中有数据时,就不再进行写的操作。
1- 1 一个读写锁的例子
import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; 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; } }
程序运行的结果:
从运行结果可以看到,当一个线程写的时候,其它的线程不允许写;而读的时候,允许多个线程同时读,且读到的数据是一致的。
在Hibernate中会有代码1-2 这样的代码:
代码1-2
User user = session.load(id,User.class);
代码1-3
User user = session.get(id,User.class);
那么代码1-2 与 1-3 有什么区别呢?
代码1-2 ,不管数据库中有没有记录,它都返回一个user对象,它是一个代理(是user的子类,可以被当做user用),是一个假的,不是一个真正的user对象。如下图:
代码1-3 ,是直接到数据库中把对象给“抓”出来,如果没有“抓”到,返回的值是NULL(空)。看看下面的这道面试题:
一个缓存系统(可以装很多的对象)的例子
import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo { private Map<String, Object> cache = new HashMap<String, Object>();//定义缓存 public static void main(String[] args) { } private ReadWriteLock rwl = new ReentrantReadWriteLock();//定义一个读写锁 /* 取数据的方法,检查内部是否有key这个数据,如果有,直接传递给程序;没有,去数据库查, 查到之后存到缓存的内存中。 下次,再有程序找该数据时,直接将缓存中的数据传给程序,不需要访问数据库 */ public Object getData(String key){ rwl.readLock().lock();//首先都上读锁*(都可以读),加锁,实现多个线程的访问 Object value = null;//注意:在try{}catch(){}中不能定义变量 try{ value = cache.get(key);//在cache中取数据 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; } }
注意代码
if(value==null){//当其它的线程检查不为空,就不用再写 value = "aaaa";//实际是去queryDB(); }
当其它的线程检查缓存中有数据时,就不再进行写的操作。
相关文章推荐
- 12.Java5读写锁技术的妙用
- 【张孝祥并发课程笔记】11:java5读写锁技术
- java5读写锁技术的妙用
- 【Java多线程与并发库】10.java5的线程锁(读写锁)技术
- 【Java多线程与并发库】10.java5的线程锁(读写锁)技术
- 多线程12_张孝祥 java5读写锁技术的妙用
- java5读写锁技术的妙用(十二)
- 【java并发】传统线程技术中的定时器技术
- 【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock
- Java并发之读写锁Lock和条件阻塞Condition的应用(转载)
- [学习笔记] Java核心技术 卷一:基础知识 并发(七)
- Java多线程编程核心技术---对象及变量的并发访问(一)
- Java并发编程与技术内幕:ArrayBlockingQueue、LinkedBlockingQueue及SynchronousQueue源码解析
- 【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock
- Java并发之读写锁Lock和条件阻塞Condition的应用
- 【Java多线程与并发库】1.传统线程技术回顾
- Java多线程与并发应用-(4)-传统线程通信技术试题
- Java 并发包中的读写锁及其实现分析
- Java并发编程有多难?这几个核心技术你掌握了吗?
- Java多线程编程核心技术---对象及变量的并发访问(二)