JUC并发编程学习笔记(八)读写锁
读写锁
ReadWriteLock
ReadWriteLock只存在一个实现类那就是ReentrantReadWriteLock,他可以对锁实现更加细粒化的控制
读的时候可以有多个阅读器线程同时参与,写的时候只希望写入线程是独占的

Demo:
package org.example.rw;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
/*
* 读读 - 可以共存 (共享锁)
* 读写 - 不能共存 (独占锁)
* 写写 - 不能共存 (独占锁)
* */
public static void main(String[] args) {
MyCache myCache = new MyCache();
// 写入:要求在写入时不能存在插队的情况,以防止写入时资源被抢占
for (int i = 1; i <= 5; i++) {
final int temp = i;
new Thread(()->{
myCache.put(""+temp,temp);
},String.valueOf(i)).start();
}
// 读取:可以插队抢占资源以实现资源的最大化利用
for (int i = 1; i <= 5; i++) {
final int temp = i;
new Thread(()->{
myCache.get(temp+"");
},String.valueOf(i)).start();
}
}
}
class MyCache{
private volatile Map<String,Object> cache = new HashMap<>();
ReadWriteLock rwLock = new ReentrantReadWriteLock();
// 细粒化控制:写 - 只希望同一时间只有一条线程写入,写入完成后再进入下一位
public void put(String key,Object value){
rwLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+":"+key+"开始写入");
cache.put(key,value);
System.out.println(Thread.currentThread().getName()+":"+key+"写入完成");
}catch (Exception e){
e.printStackTrace();
}finally {
rwLock.writeLock().unlock();
}
}
// 细粒化控制:读 - 所有人都可以读
public Object get(String key){
rwLock.readLock().lock();
Object o = null;
try {
System.out.println(Thread.currentThread().getName()+":"+key+"开始读取");
o = cache.get(key);
System.out.println(Thread.currentThread().getName()+":"+key+"读取完成");
}catch (Exception e){
e.printStackTrace();
}finally {
rwLock.readLock().unlock();
}
return o;
}
}
JUC并发编程学习笔记(八)读写锁的更多相关文章
- JUC并发编程学习笔记
JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...
- 并发编程学习笔记(6)----公平锁和ReentrantReadWriteLock使用及原理
(一)公平锁 1.什么是公平锁? 公平锁指的是在某个线程释放锁之后,等待的线程获取锁的策略是以请求获取锁的时间为标准的,即使先请求获取锁的线程先拿到锁. 2.在java中的实现? 在java的并发包中 ...
- 并发编程学习笔记(5)----AbstractQueuedSynchronizer(AQS)原理及使用
(一)什么是AQS? 阅读java文档可以知道,AbstractQueuedSynchronizer是实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量.事件,等等)提供一个框架, ...
- 并发编程学习笔记(4)----jdk5中提供的原子类及Lock使用及原理
(1)jdk中原子类的使用: jdk5中提供了很多原子类,它会使变量的操作变成原子性的. 原子性:原子性指的是一个操作是不可中断的,即使是在多个线程一起操作的情况下,一个操作一旦开始,就不会被其他线程 ...
- Java并发编程学习笔记
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...
- 并发编程学习笔记(3)----synchronized关键字以及单例模式与线程安全问题
再说synchronized关键字之前,我们首先先小小的了解一个概念-内置锁. 什么是内置锁? 在java中,每个java对象都可以用作synchronized关键字的锁,这些锁就被称为内置锁,每个对 ...
- 并发编程学习笔记(15)----Executor框架的使用
Executor执行已提交的 Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方法.通常使用 Executor 而不是显式地创建 ...
- 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理
1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...
- 并发编程学习笔记(11)----FutureTask的使用及实现
1. Future的使用 Future模式解决的问题是.在实际的运用场景中,可能某一个任务执行起来非常耗时,如果我们线程一直等着该任务执行完成再去执行其他的代码,就会损耗很大的性能,而Future接口 ...
随机推荐
- 西门子PS on eMS Standalone《导入FANUC机器人TP程序》
导入TP程序到PDPS中 右键点击左侧项目树的 "程序" --> 点击 "创建TP程序" 打开示教器 --> 点击"SELECT" ...
- Verilog实现奇分频电路
在FPGA中,计数器电路用途很广,一般计数器电路都可作为分频电路.实现占空比为50的偶分频电路很好实现.但实现占空比为50的奇分频电路有点难度.下面给出一个简单例子,记录学习奇分频电路的过程. 实现占 ...
- 基于C#的窗体阴影效果方案 - 开源研究系列文章
最近在研究C#的Winform窗体的效果,上次介绍了窗体动画效果的博文( 基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 ),这次将窗体阴影效果的方案进行一个介绍. 找了一下度娘,具 ...
- [ansible]常用内置模块
前言 ansible内置了很多模块,常用的并不多,可以通过ansible -l命令列出所有模块,使用 ansible-doc module-name 查看指定模块的帮助文档,例如:ansible-do ...
- 将实体类对象数据存入和读取进csv文件(可追加)
前言 最近公司一个新的项目,因为需要存储的数据很少,单独去部署一个数据库去存储该数据显然是不划算的,所以想的是通过存入csv文件中来代替存入数据库中.说干就干. 什么是csv文件 CSV代表逗号分隔值 ...
- [ABC151E] Max-Min Sums
2023-03-11 题目 题目传送门 翻译 翻译 难度&重要性(1~10):5 题目来源 AtCoder 题目算法 数学 解题思路 对于一个正数 \(x,x\in A\) 一定会有 \(C_ ...
- 【io_uring】简介和使用
文章目录 简介 使用 系统调用 liburing 样例 代码流程 编译 参考资料 简介 io_uring 是 Linux 在 5.1 版本引入的一套新的异步 IO 实现.相比 Linux 在 2.6 ...
- ATtiny88初体验(五):ADC
ATtiny88初体验(五):ADC ADC模块介绍 ATtiny88单片机包含一个10bit分辨率的ADC模块,拥有8个通道,最大采样率15kSPS,转换时间14us.ATtiny88的ADC参考电 ...
- 一次Python本地cache不当使用导致的内存泄露
背景 近期一个大版本上线后,Python编写的api主服务使用内存有较明显上升,服务重启后数小时就会触发机器的90%内存占用告警,分析后发现了本地cache不当使用导致的一个内存泄露问题,这里记录一下 ...
- 高德Android高性能高稳定性代码覆盖率技术实践
前言 代码覆盖率(Code coverage)是软件测试中的一种度量方式,用于反映代码被测试的比例和程度. 在软件迭代过程中,除了应该关注测试过程中的代码覆盖率,用户使用过程中的代码覆盖率也是一个非 ...