java并发初探ReentrantWriteReadLock

ReenWriteReadLock类的优秀博客

ReentrantReadWriteLock读写锁详解

Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock

ReentrantWriteReadLock类实现

@startuml
interface Lock
interface ReadWriteLock
class ReentrantReadWriteLock{
Sync sync
ReentrantReadWriteLock.ReadLock readerLock;
ReentrantReadWriteLock.WriteLock writerLock;
}
ReadWriteLock <|-- ReentrantReadWriteLock
ReentrantReadWriteLock --o ReadLock
ReentrantReadWriteLock --o WriteLock
ReentrantReadWriteLock --o Sync
AbstractQueuedSynchronizer <|- Sync
Lock <|-- ReadLock
Lock <|-- WriteLock
@enduml

特点

ReentrantWriteReadLock内部有读锁和写锁。

写锁是独占锁

当前线程持有写锁,其他线程只能等待

当其他线程拥有对象的写锁或者读锁,当前线程等待获取写锁

读锁是共享锁

没有其他线程的写锁,当前线程可以获取读锁

使用例子

package com.java.javabase.thread.base.concurrent.lock;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; @Slf4j
public class ReentranReadWriteLockTest {
/**
* @author
* @version
* @since
*/
public static void main(String[] args) {
ReentranReadWriteLockTest test =new ReentranReadWriteLockTest();
User user =test.new User("jack",test.new Count("001",1000));
for(int i=0;i<3;i++)
{
user.printCash();
user.setCash(1000);
}
} @Data
@AllArgsConstructor
@NoArgsConstructor
class Count {
private String id;
private int cash;
} @Data
class User {
private String name;
private Count count;
private ReadWriteLock readWriteLock; public User(String name, Count count) {
this.name = name;
this.count = count;
this.readWriteLock = new ReentrantReadWriteLock();
} public void setCash(final int cash) {
new Thread() {
@Override
public void run() {
readWriteLock.writeLock().lock();
try {
log.info("thread {} :user {} set cash {} start",
Thread.currentThread().getName(), name, cash);
Thread.sleep(1000);
log.info("thread {} :user {} current cash = {}",
Thread.currentThread().getName(), name, count.getCash());
count.setCash(cash);
log.info("thread {} :user {} set cash {} end",
Thread.currentThread().getName(), name, cash);
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
readWriteLock.writeLock().unlock();
}
} }.start(); } public void printCash() {
new Thread() {
@Override
public void run() {
try {
readWriteLock.readLock().lock();
log.info("thread {} :user {} get cash start", Thread.currentThread().getName(), name);
log.info("thread {} :user {} current cash = {}",
Thread.currentThread().getName(), name, count.getCash());
Thread.sleep(1000);
log.info("thread {} :user {} get cash end", Thread.currentThread().getName(), name);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
} }
}.start();
}
}
}

例子结果

2019-08-09 10:49:15,618   [Thread-0] INFO  ReentranReadWriteLockTest  - thread Thread-0 :user jack get  cash start
2019-08-09 10:49:15,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack current cash = 1000
2019-08-09 10:49:16,618 [Thread-0] INFO ReentranReadWriteLockTest - thread Thread-0 :user jack get cash end
2019-08-09 10:49:16,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 start
2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack current cash = 1000
2019-08-09 10:49:17,618 [Thread-1] INFO ReentranReadWriteLockTest - thread Thread-1 :user jack set cash 1000 end
2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash start
2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash start
2019-08-09 10:49:17,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack current cash = 1000
2019-08-09 10:49:17,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack current cash = 1000
2019-08-09 10:49:18,618 [Thread-4] INFO ReentranReadWriteLockTest - thread Thread-4 :user jack get cash end
2019-08-09 10:49:18,618 [Thread-2] INFO ReentranReadWriteLockTest - thread Thread-2 :user jack get cash end
2019-08-09 10:49:18,618 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 start
2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack current cash = 1000
2019-08-09 10:49:19,617 [Thread-5] INFO ReentranReadWriteLockTest - thread Thread-5 :user jack set cash 1000 end
2019-08-09 10:49:19,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 start
2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack current cash = 1000
2019-08-09 10:49:20,617 [Thread-3] INFO ReentranReadWriteLockTest - thread Thread-3 :user jack set cash 1000 end

java并发初探ReentrantWriteReadLock的更多相关文章

  1. java并发初探ConcurrentSkipListMap

    java并发初探ConcurrentSkipListMap ConcurrentSkipListMap以调表这种数据结构以空间换时间获得效率,通过volatile和CAS操作保证线程安全,而且它保证了 ...

  2. java并发初探ConcurrentHashMap

    java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...

  3. java并发初探ThreadPoolExecutor拒绝策略

    java并发初探ThreadPoolExecutor拒绝策略 ThreadPoolExecuter构造器 corePoolSize是核心线程池,就是常驻线程池数量: maximumPoolSize是最 ...

  4. java并发初探CyclicBarrier

    java并发初探CyclicBarrier CyclicBarrier的作用 CyclicBarrier,"循环屏障"的作用就是一系列的线程等待直至达到屏障的"瓶颈点&q ...

  5. java并发初探CountDownLatch

    java并发初探CountDownLatch CountDownLatch是同步工具类能够允许一个或者多个线程等待直到其他线程完成操作. 当前前程A调用CountDownLatch的await方法进入 ...

  6. java并发:初探sleep方法

    sleep与wait sleep是Thread方法,使得当前线程从运行态变为阻塞态.但它不会释放对象的锁. wait方法是Object方法,它的作用是使得当前拥有对象锁的线程从运行态变为阻塞态, 它会 ...

  7. java并发队列

    阻塞队列 常见的阻塞队列有ArrayBlockingQueue,LinkedBlockingDeque,LinkedBlockingQueue,这些队列有界且可以阻塞线程 ArrayBlockingQ ...

  8. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)

    AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...

  9. java并发编程资料

    并发这玩意很有用,把自己在网上看过觉得总结的很好的资料分享出来.猛击下面的地址查看吧 java并发编程:线程池的使用说明 java并发编程系列文章 Java并发性和多线程专题 并发工具类 Java 7 ...

随机推荐

  1. jQuery之绑定焦点事件(焦点事件失效)

    在使用jQuery绑定事件时,若某个事件不存在,则该事件后 绑定的事件均失效: 如图所示,若失去焦点事件checkEmail不存在, 会导致后面的事件checkMobile,和事件checkBirth ...

  2. 07-Docker-Image深入理解

    目录 07-Docker-Image深入理解 参考 镜像简介 什么是Docker镜像 什么是Docker容器 镜像结构 镜像特性 镜像层 容器层 镜像存储 07-Docker-Image深入理解 Do ...

  3. Json日期格式化,出去返回的T

    第一种办法:前端JS转换: //格式化显示json日期格式 function showDate(jsonDate) { var date = new Date(jsonDate); var forma ...

  4. mybatis Plus 多表联合查询

    //实体类package com.sk.skkill.entity; import com.baomidou.mybatisplus.annotation.TableField;import com. ...

  5. python 编程的 Style Guide

    Python 的作者既优雅又高冷又 鬼毛的 再 PEP8 里规定了 Python 程序编写规范.(风格和格式) 一.基本观念 1.可读性之上,代码被读的次数肯定比被写的次数多.因此作者十分重视代码的可 ...

  6. 吴裕雄 python 神经网络——TensorFlow 自定义损失函数

    import tensorflow as tf from numpy.random import RandomState batch_size = 8 x = tf.placeholder(tf.fl ...

  7. Java 基础--移位运算符

    移位运算符就是在二进制的基础上对数字进行平移.按照平移的方向和填充数字的规则分为三种: <<(左移).>>(带符号右移)和>>>(无符号右移). 1.左移 按 ...

  8. 大道至简第一章JAVA伪代码形式读后感

    //愚公移山: public class YuGongYiShan{ //原始需求:“惩山北之塞,出入之迂” //沟通方式:“聚室而谋曰” //项目目标:“毕力平险,指通豫南,达于汉阴” //技术方案 ...

  9. redhat7.6 DNS配置正向解析

    1.安装DNS服务 yum install bind yum install bind-chroot 安装完的配置文件/etc/named.conf 启动systemctl start named.s ...

  10. centos7搭建hadoop2.10完全分布式

    本篇介绍在centos7中大家hadoop2.10完全分布式,首先准备4台机器:1台nn(namenode);3台dn(datanode) IP hostname 进程 192.168.30.141 ...