转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558073.html 

普通的锁在对某一内容加锁后,其他线程是不能访问的。但是我们要考虑这种情况:如果当前加锁的内容中,有些操作是可以并发执行的,有些是不可以并发,两种操作之间又存在互斥,怎么才能最优化地加锁呢?我们引入了ReadWriteLock,人为地将这两种操作划分为 读、写 操作。(注意:这里的读、写 不是完全意义上的读写,只是用来标识两种加锁的操作),根据操作所加锁的不同,操作之间的互斥关系如下:读——读不互斥;读——写互斥;写——写互斥。也就是说,只有加了读锁的代码块之间可以并发执行,加了读锁的代码块与加了写锁的代码块互斥,加了写锁的代码块之间也互斥执行。

一:使用

创建读写锁:ReadWriteLock接口继承自Lock接口,实现类是ReentrantReadWriteLock。所以使用ReentrantReadWriteLock来创建读写锁,可以在构造函数中指明是否是公平锁。

获取读锁:读锁通过ReentrantReadWriteLock对象的 readLock() 返回一个Lock接口的实现类。

获取写锁:写锁通过ReentrantReadWriteLock对象的 writeLock() 返回一个Lock接口的实现类。

加锁:在需要加锁的地方用读/写锁的lock()加锁。

释放锁:在需要解锁的地方用读/写锁的 unlock()解锁。

二:例子

private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
public void run() {
if (ischeck) {
//上读锁
readLock.lock();
System.out.println("读:" + name + "正在查询" + myCount + "账户,当前金额为" + myCount.getCash());
//释放读锁
readLock.unlock();
} else {
//上写锁
writeLock.lock();
System.out.println("写:" + name + "正在操作" + myCount + "账户,金额为" + iocash +",当前金额为" + myCount.getCash());
myCount.setCash(myCount.getCash() + iocash);
System.out.println("写:" + name + "操作" + myCount + "账户成功,金额为" + iocash +",当前金额为" + myCount.getCash());
//释放写锁
writeLock.unlock();
}
}

三:JDK8中的改进——StampedLock

StampedLock是ReadWriteLock的一个改进。StampedLock与ReadWriteLock的区别在于,StampedLock认为读不应阻塞写。StampedLock认为读写互斥应该是指——不让读重复读同一数据,而不是不让写线程写。

StampedLock是一种偏向于写线程的改进,解决了读多写少时,使用ReadWriteLock会产生写线程饥饿现象。

Java多线程之ReadWriteLock读写锁简介与使用教程的更多相关文章

  1. java多线程 -- ReadWriteLock 读写锁

    写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...

  2. 12. ReadWriteLock 读写锁

    package com.gf.demo11; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent. ...

  3. ReadWriteLock读写锁(八)

    前言:在JUC ReentrantReadWriteLock是基于AQS实现的读写锁实现. ReadWriteLock中定义了读写锁需要实现的接口,具体定义如下: public interface R ...

  4. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

  5. GUC-9 ReadWriteLock : 读写锁

    import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWrit ...

  6. ReadWriteLock: 读写锁

    ReadWriteLock: 读写锁 ReadWriteLock: JDK1.5提供的读写分离锁,采用读写锁分离可以有效帮助减少锁竞争. 特点: 1).使用读写锁.当线程只进行读操作时,可以允许多个线 ...

  7. 22.ReadWriteLock读写锁

    import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.R ...

  8. Java多线程之ConcurrentSkipListMap深入分析(转)

    Java多线程之ConcurrentSkipListMap深入分析   一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...

  9. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

随机推荐

  1. TextView 中文文档

    属性名称 描述 android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web/email/phone/map/all) ...

  2. 《嵌入式Linux开发实用教程》

    <嵌入式Linux开发实用教程> 基本信息 作者: 朱兆祺    李强    袁晋蓉 出版社:人民邮电出版社 ISBN:9787115334831 上架时间:2014-2-13 出版日期: ...

  3. Ubuntu 查找文件的方法

    1. whereis+文件名 用于程序名的搜索,搜索结果只限于二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s),如果省略参数,则返回所有信息. 2. find / -name ...

  4. Spring注解详解@Repository、@Component、@Service 和 @Constroller

    概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...

  5. c#利用SWIG调用c++dll学习总结【转】

    开发环境: 操作系统:windows 7 IDE:Microsoft Visual Studio Professional 2015 SWIG: 3.0.12 swig的介绍 详细介绍可看官网,一下贴 ...

  6. 如何配置官方peerDroid,使其运行起来

    一.Peer Droid是JXME协议到android平台的移植,开发者可以利用它来实现android设备以及传统PC机通讯的应用程序,peerDroid的官方demo主要是实现PC端peer和and ...

  7. RNN(Recurrent Neural Networks)公式推导和实现

    RNN(Recurrent Neural Networks)公式推导和实现 http://x-algo.cn/index.php/2016/04/25/rnn-recurrent-neural-net ...

  8. 如何给USB移动硬盘格式化分区

    硬盘盒装好后,插在电脑USB接口上,电脑正常识别到移动硬盘后,但因为全新硬盘没有分区,在"我的电脑"里是看不到盘符的.下面以40G移动硬盘分区讲一下硬盘如何分区.1.操作系统最好是 ...

  9. 一个ActiveX control的创建过程

    创建 根据这篇文章的介绍:http://www.cnblogs.com/time-is-life/p/6354152.html 来创建,里面包含了创建的基本过程以及属性事件方法的使用. 使用: 参考文 ...

  10. js 前加分号和感叹号的含义

    ;!function(){}();  ;!有什么用? 从语法上来开.Javascript中分号表示语句结束,在开头加上.可能是为了压缩的时候和别的方法切割一下,表示一个新的语句開始.所以,假设在一个单 ...