JUC----04
1.1 读写问题
ReadWriteLockUnsafeDemo:
public class ReadWriteLockUnsafeDemo {
// TODO: 2020/7/25 模拟多线程对公共资源类的读和写操作,没有加锁,不安全
static class Cache {
private HashMap<String, Object> cache = new HashMap<>();
//写入缓存
public void put(String key, Object val) {
try {
System.out.println(Thread.currentThread().getName() + " 开始写入");
cache.put(key, val);
System.out.println(Thread.currentThread().getName() + " 写入完成");
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
//从缓存中读取数据
public void get(String key) {
try {
System.out.println(Thread.currentThread().getName() + " 开始读取");
Object obj = cache.get(key);
System.out.println(Thread.currentThread().getName() + " 读取完成 : " + obj);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
public static void main(String[] args) {
Cache cache = new Cache();
for (int i = 0; i < 5; ++i) {
final int tempI = i;
new Thread(() -> {
cache.put(String.valueOf(tempI), tempI);
}).start();
}
for (int i = 0; i < 5; ++i) {
final int tempI = i;
new Thread(() -> {
cache.get(String.valueOf(tempI));
}).start();
}
}
}
运行结果:
Thread-0 开始写入
Thread-1 开始写入
Thread-1 写入完成
Thread-0 写入完成
Thread-2 开始写入
Thread-2 写入完成
Thread-3 开始写入
Thread-3 写入完成
Thread-5 开始读取
Thread-5 读取完成 : 0
Thread-4 开始写入
Thread-4 写入完成
Thread-6 开始读取
Thread-6 读取完成 : 1
Thread-7 开始读取
Thread-7 读取完成 : 2
Thread-8 开始读取
Thread-9 开始读取
Thread-9 读取完成 : 4
Thread-8 读取完成 : 3
首先我们可以发现在写操作的时候线程发生的争抢。
ReadWriteLockDemo:
public class ReadWriteLockDemo {
/**
* * 读-读 : 无锁
* * 读-写 : 锁
* * 写-写 : 锁
*/
//模拟缓存被读和被写
static class Cache {
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private HashMap<String, Object> cache = new HashMap<>();
//写入缓存
public void put(String key, Object val) {
/**
* 加写锁
*/
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 开始写入");
cache.put(key, val);
System.out.println(Thread.currentThread().getName() + " 写入完成");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
//从缓存中读取数据
public void get(String key) {
/**
* 加读锁
*/
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 开始读取");
Object obj = cache.get(key);
System.out.println(Thread.currentThread().getName() + " 读取完成 : " + obj);
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
public static void main(String[] args) {
Cache cache = new Cache();
for (int i = 0; i < 5; ++i) {
final int tempI = i;
new Thread(() -> {
cache.put(String.valueOf(tempI), tempI);
}).start();
}
for (int i = 0; i < 5; ++i) {
final int tempI = i;
new Thread(() -> {
cache.get(String.valueOf(tempI));
}).start();
}
}
}
运行结果:
Thread-0 开始写入
Thread-0 写入完成
Thread-1 开始写入
Thread-1 写入完成
Thread-2 开始写入
Thread-2 写入完成
Thread-3 开始写入
Thread-3 写入完成
Thread-4 开始写入
Thread-4 写入完成
Thread-5 开始读取
Thread-5 读取完成 : 0
Thread-6 开始读取
Thread-6 读取完成 : 1
Thread-7 开始读取
Thread-7 读取完成 : 2
Thread-8 开始读取
Thread-8 读取完成 : 3
Thread-9 开始读取
Thread-9 读取完成 : 4
可以看到写操作保证了原子性,读操作不加锁任意读。
这里的读操作不加锁,可能有些人会说既然不加锁,那为什么这一步要获取读锁?

这里的加锁是为了和读操作分离开来,保证上面的读锁释放完后(读操作做完了)再进行读,而各个读线程之间是不加锁的。
java这部分东西都藏在源码里了,我个人认为上面的代码严格来说属于写优先算法。写写互斥,写优先。
熟悉操作系统的都知道读写问题一般分三种:
- 读优先
- 写优先
- 读写公平
JUC----04的更多相关文章
- Java多线程系列--“JUC集合”04之 ConcurrentHashMap
概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程系列--“JUC原子类”04之 AtomicReference原子类
概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...
- Java多线程系列--“JUC线程池”04之 线程池原理(三)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...
- java多线程系类:JUC线程池:04之线程池原理(三)(转)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--"基础篇& ...
- java多线程系类:JUC原子类:04之AtomicReference原子类
概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...
- Java多线程系列 JUC线程池04 线程池原理解析(三)
转载 http://www.cnblogs.com/skywang12345/p/3509954.html https://blog.csdn.net/qq_22929803/article/det ...
- JUC 并发编程--04 常用的辅助类CountDownLatch , CyclicBarrier , Semaphore , 读写锁 , 阻塞队列,CompletableFuture(异步回调)
CountDownLatch 相当于一个减法计数器, 构造方法指定一个数字,比如6, 一个线程执行一次,这个数字减1, 当变为0 的时候, await()方法,才开始往下执行,, 看这个例子 Cycl ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...
随机推荐
- pycharm控制台输出的日志全是红色的字体?
问题:logging在pycharm控制台输出的日志的字体全是红色的,怎么办? 图片描述: 解决办法:设置 -> 搜索“Console” -> 结果:改完立马生效
- 手写IOC容器
IOC(控制翻转)是程序设计的一种思想,其本质就是上端对象不能直接依赖于下端对象,要是依赖的话就要通过抽象来依赖.这是什么意思呢?意思就是上端对象如BLL层中,需要调用下端对象的DAL层时不能直接调用 ...
- HttpServletRequest、HttpServletResponse
doGet()/doPost()方法都有两个参数,一个为代表请求的request,另一个代表响应response. request是获取前台传递的内容,response是反馈给前台数据 HttpSer ...
- 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化
<数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...
- Python获取当前时间_获取格式化时间_格式化日期
Python获取当前时间_获取格式化时间: Python获取当前时间: 使用 time.time( ) 获取到距离1970年1月1日的秒数(浮点数),然后传递给 localtime 获取当前时间 #使 ...
- SUM and COUNT -- SQLZOO
SUM and COUNT 注意:where语句中对表示条件的需要用单引号, 下面的译文使用的是有道翻译如有不正确,请直接投诉有道 01.Show the total population of th ...
- PHP usort() 函数
------------恢复内容开始------------ 实例 使用用户自定义的比较函数对数组 $a 中的元素进行排序:Sort the elements of the $a array usin ...
- PHP date_interval_format() 函数
------------恢复内容开始------------ 计算两个日期间的间隔,然后格式化时间间隔: 实例 <?php $date1=date_create("2013-01-01 ...
- PHP abs() 函数
实例 返回不同数的绝对值: <?phpecho(abs(6.7) . "<br>");echo(abs(-6.7) . "<br>" ...
- 关于python中的 take no arguments 的解决方法
针对第四章编写的代码出现的错误做一个总结 Traceback (most recent call last): File "H:\image\chapter4\p81_chongxie.py ...