java 多线程 ReentrantReadWriteLock 使用
2015-09-14 14:48
1016 查看
原文来自 http://www.linuxidc.com/Linux/2014-06/103457.htm Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须用同一个Lock对象。 读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁! ReentrantReadWriteLock会使用两把锁来解决问题,一个读锁,一个写锁 线程进入读锁的前提条件:没有其他线程的写锁,没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。 线程进入写锁的前提条件:没有其他线程的读锁,没有其他线程的写锁。 Java多线程:一道阿里面试题的分析与应对 http://www.linuxidc.com/Linux/2014-03/98715.htm Java1.5后的多线程框架 http://www.linuxidc.com/Linux/2014-02/96879.htm Java多线程和同步的理解 http://www.linuxidc.com/Linux/2013-12/93691.htm Java中两种实现多线程方式的对比分析 http://www.linuxidc.com/Linux/2013-12/93690.htm Java利用多线程计算目录数据大小 http://www.linuxidc.com/Linux/2013-09/90715.htm Java多线程向数据库写入数据 http://www.linuxidc.com/Linux/2013-09/90297.htm 总结这个锁机制的特性: (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。 (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵. (c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。 (d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。 (e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出UnsupportedOperationException异常。 代码典例: package cn.itcast.lesson12; import java.io.ObjectOutputStream.PutField; import java.util.Random; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.omg.CORBA.PUBLIC_MEMBER; 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) { //传入一个data值 q3.put(new Random().nextInt(10000)); } } }.start(); } } } class Queue3{ private Object data = null;//共享數據,只能有一个线程能写该数据,但有多个线程能读该数据 private ReentrantReadWriteLock rw1 = new ReentrantReadWriteLock(); public void get(){ rw1.readLock().lock(); System.out.println(Thread.currentThread().getName()+" be ready to read data!"); try{ Thread.sleep((long) (Math.random()*1000)); }catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"have read data: " + data); rw1.readLock().unlock(); } public void put(Object data){ rw1.writeLock().lock(); System.out.println(Thread.currentThread().getName()+" be ready to write data!"); try{ Thread.sleep((long) (Math.random()*1000)); }catch (Exception e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName()+"have write data: "+ data); rw1.writeLock().unlock(); } } 结果浏览: 无 结果分析:.ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。
相关文章推荐
- java设计模式学习 ----- 代理模式(Proxy)
- 基于Struts2框架实现登录案例
- Java压缩文件
- 十进制转换为任意进制 java实现
- Spring MVC form errors tag example
- URI in java
- spring中@Scope作用域的注解
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
- java.lang.OutOfMemoryError: PermGen space及其解决方法【使用webservice请求web服务的时候报此错误】
- java abstract基础
- java cookie
- Java异常体系
- Java Synchronized Blocks vs. Methods
- JAVA使用pdfbox将pdf转换成图片
- Struts2注解解析
- [Java]读取文件方法大全(转载)
- Struts2 注解
- java多线程
- 浅谈Java中的hashcode方法
- Java中Integer与int类型的装箱和拆箱