`
gelu2
  • 浏览: 7240 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

java新特性——读写锁ReadWriteLock

阅读更多
from URL : http://hi.baidu.com/zhizhesky/blog/item/cabcbb515b9b6808377abe5f.html

在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁。为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。
Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,详细的API可以查看JavaAPI文档。
ReentrantReadWriteLock 和 ReentrantLock 不是继承关系,但都是基于 AbstractQueuedSynchronizer 来实现。

lock方法 是基于CAS 来实现的

注意: 在同一线程中,持有读锁后,不能直接调用写锁的lock方法 ,否则会造成死锁。

下面这个例子是在文例子的基础上,将普通锁改为读写锁,并添加账户余额查询的功能,代码如下:
[java] view plain copy
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.locks.ReadWriteLock; 
import java.util.concurrent.locks.ReentrantReadWriteLock; 
 
/** 
public class Test { 
         public static void main(String[] args) { 
                 //创建并发访问的账户 
                 MyCount myCount = new MyCount("95599200901215522", 10000); 
                 //创建一个锁对象 
                 ReadWriteLock lock = new ReentrantReadWriteLock(false); 
                 //创建一个线程池 
                 ExecutorService pool = Executors.newFixedThreadPool(2); 
                 //创建一些并发访问用户,一个信用卡,存的存,取的取,好热闹啊 
                 User u1 = new User("张三", myCount, -4000, lock, false); 
                 User u2 = new User("张三他爹", myCount, 6000, lock, false); 
                 User u3 = new User("张三他弟", myCount, -8000, lock, false); 
                 User u4 = new User("张三", myCount, 800, lock, false); 
                 User u5 = new User("张三他爹", myCount, 0, lock, true); 
                 //在线程池中执行各个用户的操作 
                 pool.execute(u1); 
                 pool.execute(u2); 
                 pool.execute(u3); 
                 pool.execute(u4); 
                 pool.execute(u5); 
                 //关闭线程池 
                 pool.shutdown(); 
         } 

 
/** 
class User implements Runnable { 
         private String name;                 //用户名 
         private MyCount myCount;         //所要操作的账户 
         private int iocash;                 //操作的金额,当然有正负之分了 
         private ReadWriteLock myLock;                 //执行操作所需的锁对象 
         private boolean ischeck;         //是否查询 
 
         User(String name, MyCount myCount, int iocash, ReadWriteLock myLock, boolean ischeck) { 
                 this.name = name; 
                 this.myCount = myCount; 
                 this.iocash = iocash; 
                 this.myLock = myLock; 
                 this.ischeck = ischeck; 
         } 
 
         public void run() { 
                 if (ischeck) { 
                         //获取读锁 
                         myLock.readLock().lock(); 
                         System.out.println("读:" + name + "正在查询" + myCount + "账户,当前金额为" + myCount.getCash()); 
                         //释放读锁 
                         myLock.readLock().unlock(); 
                 } else { 
                         //获取写锁 
                         myLock.writeLock().lock(); 
                         //执行现金业务 
                         System.out.println("写:" + name + "正在操作" + myCount + "账户,金额为" + iocash +",当前金额为" + myCount.getCash()); 
                         myCount.setCash(myCount.getCash() + iocash); 
                         System.out.println("写:" + name + "操作" + myCount + "账户成功,金额为" + iocash +",当前金额为" + myCount.getCash()); 
                         //释放写锁 
                         myLock.writeLock().unlock(); 
                 } 
         } 

 
/** 
class MyCount { 
         private String oid;         //账号 
         private int cash;             //账户余额 
 
         MyCount(String oid, int cash) { 
                 this.oid = oid; 
                 this.cash = cash; 
         } 
 
         public String getOid() { 
                 return oid; 
         } 
 
         public void setOid(String oid) { 
                 this.oid = oid; 
         } 
 
         public int getCash() { 
                 return cash; 
         } 
 
         public void setCash(int cash) { 
                 this.cash = cash; 
         } 
 
         @Override 
         public String toString() { 
                 return "MyCount{" + 
                                 "oid='" + oid + '\'' + 
                                 ", cash=" + cash + 
                                 '}'; 
         } 

写:张三正在操作MyCount{oid='95599200901215522', cash=10000}账户,金额为-4000,当前金额为10000 
写:张三操作MyCount{oid='95599200901215522', cash=6000}账户成功,金额为-4000,当前金额为6000 
写:张三他弟正在操作MyCount{oid='95599200901215522', cash=6000}账户,金额为-8000,当前金额为6000 
写:张三他弟操作MyCount{oid='95599200901215522', cash=-2000}账户成功,金额为-8000,当前金额为-2000 
写:张三正在操作MyCount{oid='95599200901215522', cash=-2000}账户,金额为800,当前金额为-2000 
写:张三操作MyCount{oid='95599200901215522', cash=-1200}账户成功,金额为800,当前金额为-1200 
读:张三他爹正在查询MyCount{oid='95599200901215522', cash=-1200}账户,当前金额为-1200 
写:张三他爹正在操作MyCount{oid='95599200901215522', cash=-1200}账户,金额为6000,当前金额为-1200 
写:张三他爹操作MyCount{oid='95599200901215522', cash=4800}账户成功,金额为6000,当前金额为4800 
 
Process finished with exit code 0 
分享到:
评论

相关推荐

    同步 读写锁 readwriteLock

    读写锁的设计实现等.。。。。。。。。。。。。。。。。。。。。

    Java多线程编程之读写锁ReadWriteLock用法实例

    主要介绍了Java多线程编程之读写锁ReadWriteLock用法实例,本文直接给出编码实例,需要的朋友可以参考下

    Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁

    主要介绍了Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁,本文讲解了ReentrantLock概况、Lock接口、Lock使用、轮询锁的和定时锁、公平性、可中断获锁获取操作等内容,需要的朋友可以参考下

    java并发工具包 java.util.concurrent中文版用户指南pdf

    java_util_concurrent_user_guide_cn.pdf 内容预览: ...21. 读写锁 ReadWriteLock 22. 原子性布尔 AtomicBoolean 23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReference

    java并发工具包详解

    1. java.util.concurrent - Java 并发工具包 ...21. 读写锁 ReadWriteLock 22. 原子性布尔 AtomicBoolean 23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReference

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf

    java_util_concurrent_user_guide_cn.pdf 内容预览: 1.... 读写锁 ReadWriteLock 22. 原子性布尔 AtomicBoolean 23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReferenc

    一个小的java Demo , 非常适合Java初学者学习阅读.rar

    使用 ForkJoinPool 进行分叉和合并,锁 Lock,读写锁 ReadWriteLock 原子性长整型 AtomicLong,原子性引用型 AtomicReference 修改数据: 一 服务端修改数据: 一 文章知识点与官方知识档案匹配,可进一步学习相关...

    Java多线程之readwritelock读写分离的实现代码

    主要介绍了Java多线程之readwritelock读写分离的相关内容,文中涉及具体实例代码,具有一定参考价值,需要的朋友可以了解下。

    e语言-易语言线程安全之原子锁与读写锁

    局部变量 rwLock, ReadWriteLock ' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中。 ***注意不要修改本子程序的名称、...

    Java并发工具包java.util.concurrent用户指南中英文对照阅读版

    本资源包含两个 pdf 文档,一本根据 Jakob Jenkov 最新博客 ...21. 读写锁 ReadWriteLock 22. 原子性布尔 AtomicBoolean 23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReference

    ReadWriteLock:使用 POSIX 信号量用 C 编写的读者首选读写锁

    C 语言中的可移植读写锁该项目旨在为 C 创建一个易于使用且可移植的读写锁。这是通过使用 POSIX 信号量和“隐藏”结构声明来实现的,以避免滥用提供的 API。 这个锁是reader-preferred ,这意味着一个 writer 必须...

    java并发包资源

    本资源包含两个 pdf 文档,一本根据 Jakob Jenkov 最新博客 ...21. 读写锁 ReadWriteLock 22. 原子性布尔 AtomicBoolean 23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReference

    详解java多线程的同步控制

    目录线程安全 Thread Safety重入锁 ReentrantLock读写锁 ReadWriteLock倒计数器 CountDownLatch循环栅栏 CyclicBarrier信号量 Semaphore 线程安全 Thread Safety JMM JMM(Java Memory Model)是一种基于计算机内存...

    Java语言ReadWriteLock特性实例测试

    主要介绍了Java语言ReadWriteLock特性实例测试,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    ReadWriteLock

    一个Windows下C++读写锁的代码,实现共享读,独占写

    23 按需上锁—ReadWriteLock详解.pdf

    Java并发编程学习宝典(漫画版),Java并发编程学习宝典(漫画版)Java并发编程学习宝典(漫画版)Java并发编程学习宝典(漫画版)Java并发编程学习宝典(漫画版)Java并发编程学习宝典(漫画版)Java并发编程学习...

    Java 8无人谈及的八大功能

    时间戳锁 ...Java8引入了一种新的读写锁——叫做时间戳锁。好消息是这个家伙真的非常快。坏消息是它使用起来更复杂,有更多的状态需要处理。并且它是不可重入的,这意味着一个线程有可能跟自己死锁。  

    ReadWriteLock的使用

    ReadWriteLock的使用,实际上由于ReadWriteLock是一个接口,所以实际使用的是ReentrantReadWriteLock子类。同时ReadWriteLock的使用其实也是比较简单的,就是读写的锁的使用以及注意事项而已。

    java并发编程-AQS和JUC实战

    ReadWriteLock读写锁;CountDownLatch计时器;CyclicBarrier循环栅栏; 重⼊锁可以完全替代synchronized关键字。在JDK5.0的早期版本中,重⼊锁的性能远远好于 synchronized,但从JDK6.0开始,JDK在synchronized上做...

    homework-ReadWriteLock-KristampsW-main.zip

    读写锁源码

Global site tag (gtag.js) - Google Analytics