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的更多相关文章

  1. Java多线程系列--“JUC集合”04之 ConcurrentHashMap

    概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...

  2. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  3. Java多线程系列--“JUC原子类”04之 AtomicReference原子类

    概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...

  4. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  5. java多线程系类:JUC线程池:04之线程池原理(三)(转)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--"基础篇& ...

  6. java多线程系类:JUC原子类:04之AtomicReference原子类

    概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...

  7. Java多线程系列 JUC线程池04 线程池原理解析(三)

    转载 http://www.cnblogs.com/skywang12345/p/3509954.html  https://blog.csdn.net/qq_22929803/article/det ...

  8. JUC 并发编程--04 常用的辅助类CountDownLatch , CyclicBarrier , Semaphore , 读写锁 , 阻塞队列,CompletableFuture(异步回调)

    CountDownLatch 相当于一个减法计数器, 构造方法指定一个数字,比如6, 一个线程执行一次,这个数字减1, 当变为0 的时候, await()方法,才开始往下执行,, 看这个例子 Cycl ...

  9. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  10. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

随机推荐

  1. Python网络编程基础|百度网盘免费下载|零基础入门学习资料

    百度网盘免费下载:Python网络编程基础|零基础学习资料 提取码:k7a1 目录: 第1部分 底层网络 第1章 客户/服务器网络介绍 第2章 网络客户端 第3章 网络服务器 第4章 域名系统 第5章 ...

  2. 【IDEA】HTML通过servlet3.0注解名提交表单到servlet类找不到页面的问题

    IDEA一时爽,摸不着头的BUG火葬场 这个问题困扰我整整一天一夜,先是代码检查路径设置找不出问题,后面换tomcat版不行,抱着侥幸心理换IDEA版本意料之中还是没解决问题. 都快想秃了最后终于完美 ...

  3. Django---博客项目实战

    1.urls from django.conf.urls import url from django.contrib import admin from blog import views urlp ...

  4. Day12_搜索过滤

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"乐优商城"获取视频和教程资料! b站在线视频 0.学习 ...

  5. Python File fileno() 方法

    概述 fileno() 方法返回一个整型的文件描述符(file descriptor FD 整型),可用于底层操作系统的 I/O 操作.高佣联盟 www.cgewang.com 语法 fileno() ...

  6. 好用的连接池-HikariCP

    在Springboot的发展历程中,默认的DataSource也从Springboot1.x的tomcat连接池到Springboot2.x的HikariCP.关于HikariCP的简单使用在配置多数 ...

  7. Archlinux 最新安装方法 (2020.07.01-x86_64)之虚拟机 BIOS 安装

    话不多说,直接上干货 准备 去Arch 官网,选择一个合适的国内镜像站下载 Arch 安装包 ISO,地址如下: https://www.archlinux.org/download/ 一.创建虚拟机 ...

  8. .Net Core 3.0下AOP试水~~

    昨天躺了一下3.0的依赖注入的雷 今天顺势把AOP做了一下调整,比如自动化的AOP注入 默认的Program里面的CreateHostBuilder方法增加一行 public static IHost ...

  9. Spring Boot上传文件(带进度条)

    Spring Boot 上传文件(带进度条)# 配置文件 spring: freemarker: template-loader-path: classpath:/static/ ##Spring B ...

  10. 前端面试基础题:Ajax原理

    Ajax 的原理简单来说是在⽤户和服务器之间加了—个中间层( AJAX 引擎),通过XmlHttpRequest 对象来向服务器发异步请求,从服务器获得数据,然后⽤ javascrip t 来操作 D ...