转载原文:http://blog.csdn.net/john8169/article/details/53228016

读写锁:  分为读锁和写锁,多个读锁不互斥,读锁和写锁互斥,这是有JVM自己控制的.如果代码只能读取数据,可以多人同时读,不能同时写,上读锁,

如果代码要修改数据,只能有一个人写,而且不能同时读取.上写锁.

线程进入写锁的前提条件:

  没有其他线程的读锁和写锁;

线程进入读锁的前提条件:

  没有其他线程的写锁或写请求

(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 com.imooc.locks;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; public class Queue { private Object data = null;//共享数据,只能有一个线程写该数据,但可以多个线程读取该数据 //读写锁
ReadWriteLock rwl = new ReentrantReadWriteLock(); // 相当于读操作
public void get() {
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();
}
} // 相当于写操作
public void put(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();
}
} }
package com.imooc.locks;

import java.util.Random;

public class ReadWriteLockTest {

    public static void main(String[] args) {

        final Queue q3 = new Queue();  

        for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.get();
}
}
}.start();
new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-0have read data :null
Thread-2have read data :null
Thread-4have read data :null
Thread-1 be ready to write data!
Thread-1 have write data: 3101
Thread-1 be ready to write data!
Thread-1 have write data: 8258
Thread-1 be ready to write data!
Thread-1 have write data: 7242
Thread-3 be ready to write data!
Thread-3 have write data: 4810
Thread-5 be ready to write data!
Thread-5 have write data: 7597
Thread-5 be ready to write data!
Thread-5 have write data: 8800
Thread-0 be ready to read data!
Thread-4 be ready to read data!
Thread-2 be ready to read data!
Thread-0have read data :8800
Thread-2have read data :8800
Thread-4have read data :8800
Thread-1 be ready to write data!
Thread-1 have write data: 6606
Thread-1 be ready to write data!
Thread-1 have write data: 5436
Thread-1 be ready to write data!
Thread-1 have write data: 3912
Thread-1 be ready to write data!
Thread-1 have write data: 7689
Thread-3 be ready to write data!
Thread-3 have write data: 3102
Thread-3 be ready to write data!
Thread-3 have write data: 466
Thread-3 be ready to write data!
Thread-3 have write data: 7377
Thread-3 be ready to write data!
Thread-3 have write data: 5461
Thread-3 be ready to write data!
Thread-3 have write data: 175
Thread-3 be ready to write data!
Thread-3 have write data: 8805
Thread-3 be ready to write data!
Thread-3 have write data: 8898
Thread-5 be ready to write data!
Thread-5 have write data: 8823
Thread-5 be ready to write data!
Thread-5 have write data: 5615
Thread-5 be ready to write data!
Thread-5 have write data: 8118
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-0have read data :8118
Thread-2have read data :8118
Thread-4have read data :8118
Thread-1 be ready to write data!
Thread-1 have write data: 5314
Thread-1 be ready to write data!

  从打印结果可以看出:

多个线程可以同时读取数据,但是只有一个线程可以写数据;

线程高级篇-读写锁ReentrantReadWriteLock的更多相关文章

  1. UNIX环境高级编程——线程同步之读写锁以及属性

    读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...

  2. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  3. java 可重入读写锁 ReentrantReadWriteLock 详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt206 读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只 ...

  4. [图解Java]读写锁ReentrantReadWriteLock

    图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWr ...

  5. 轻松掌握java读写锁(ReentrantReadWriteLock)的实现原理

    转载:https://blog.csdn.net/yanyan19880509/article/details/52435135 前言 前面介绍了java中排它锁,共享锁的底层实现机制,本篇再进一步, ...

  6. [源码分析]读写锁ReentrantReadWriteLock

    一.简介 读写锁. 读锁之间是共享的. 写锁是独占的. 首先声明一点: 我在分析源码的时候, 把jdk源码复制出来进行中文的注释, 有时还进行编译调试什么的, 为了避免和jdk原生的类混淆, 我在类前 ...

  7. Java并发(十):读写锁ReentrantReadWriteLock

    先做总结: 1.为什么用读写锁 ReentrantReadWriteLock? 重入锁ReentrantLock是排他锁,在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服 ...

  8. 深入浅出 Java Concurrency (13): 锁机制 part 8 读写锁 (ReentrantReadWriteLock) (1)

      从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock). ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念.前面的章节中一 ...

  9. Java读写锁(ReentrantReadWriteLock)学习

    什么是读写锁 平时,我们常见的synchronized和Reentrantlock基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,哪怕是读操作.而读写锁是维护了一对锁(一个读锁和一个写锁), ...

随机推荐

  1. Unicode、UTF-8 和 ISO8859-1到底有什么区别

    说明:本文转载于新浪博客,旨在方便知识总结.原文地址:http://blog.sina.com.cn/s/blog_673c81990100t1lc.html 本文主要包括以下几个方面:编码基本知识, ...

  2. 记一次小型生产事故 | BeyondComper跨编码方式复制文件内容

    前言 今天组长在做站内巡检的时候,发现header内有一条meta标签的content显示为乱码. <meta name="description" content=&quo ...

  3. $($('.className').html( )选择器的工作原理

    $($('.slot')[0]).html('<img src = "' + images[slotOne-1] + '">');

  4. nio系列(一)---nio重要组成

    nio重要组成部分 前言:通过本文可以了解nio的重要组成部分,了解完基础的内容后后面理解才会简单一点.下一篇会讲讲nio的应用和io的对比.如果有不正确的地方还望指正. channel chanel ...

  5. 一些常用的集合工具的代码块(缓慢更新XD)

    鱼的记忆   我发现在项目中常常要用到一些集合的处理,不同的项目我经常会编写自己的集合工具代码块,后来我发现我总是在写一样的代码块(可能是我记性不好吧:),毕竟鱼的记忆只有7秒),所以我意识到了是时候 ...

  6. python 第三天

    函数 函数的定义 def 语句定义函数,格式如下: def sayHello(name): if(name): print('hello',name) else: print('hello,','I\ ...

  7. 1、初识socket

    经过近一个半月的学习我们已经度过了python基础的阶段,今天我们开始学习python网络编程,没有难以理解的逻辑,更注重的是记忆. 对网络协议和基础没有概念的可以在阅读本文前预习计算机基础3.网络协 ...

  8. nRF24LE1/nRF31512烧录驱动开发

    一丶协议分析 这两种芯片都是programming through SPI,烧录要用到的引脚有 SPI_MOSI_Port :数据输入: SPI_MISO_Port :数据输出: SPI_SCLK_P ...

  9. 压缩感知中的数学知识:稀疏、范数、符号arg min

    转自:http://blog.csdn.net/jbb0523/article/details/40262629 1.稀疏:什么是K稀疏呢? 在压缩感知里经常提到 "K稀疏" 的概 ...

  10. FxZ,C#开发职位面试测试题(30分钟内必须完成)

    1. Refactor the following code (C#) to use polymorphism instead of if-else. Please provide your answ ...