当前位置:网站首页>JUC并发编程基础(8)--读写锁
JUC并发编程基础(8)--读写锁
2022-07-24 05:21:00 【aMythhhhh】
读写锁(重点)
悲观锁和乐观锁
悲观锁不支持并发操作,效率很低。
乐观锁通过给操作资源加入版本号,多个线程可以同时操作,谁先提交,版本号更新,后面的线程不能提交。
表锁、行锁
操作资源为一张数据表时,表锁直接锁一张表,哪怕只操作一行数据。
行锁则锁其中一行,另外的行数可以被其它线程操作,但行锁可能会出现死锁情况。
读锁、写锁
读锁:共享锁,发生死锁
写锁:独占锁,发生死锁
知识补充:内存可见性问题
小例子:
/** * 变量的内存可见性例子 * * @author star */ public class VolatileExample { /** * main 方法作为一个主线程 */ public static void main(String[] args) { MyThread myThread = new MyThread(); // 开启线程 myThread.start(); // 主线程执行 for (; ; ) { if (myThread.isFlag()) { System.out.println("主线程访问到 flag 变量"); } } } } /** * 子线程类 */ class MyThread extends Thread { private boolean flag = false; @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 修改变量值 flag = true; System.out.println("flag = " + flag); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } }这里控制台一直都不输出主线程访问到 flag 变量这句话,是因为主线程读取到的flag值是false,但是在MyThread线程中,明明已经将flag值设置成了true,为什么读不到呢?这就涉及到Java内存模型的知识,涉及到内存可见性问题。
Java内存模型,简称JMM,是Java虚拟机所定义的,是一种并发编程的底层模型机制。
总的来说就是JMM 定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。
可能线程更改了本地内存中的副本值,但是JMM没有及时的更新到主内存 ,导致其它线程取到的仍然是之前的值,或者说线程没能将主内存中最新值同步到工作内存中,就会导致这样的可见性问题。
内存可见性是指当一个线程修改了某个变量的值,其它线程总是能知道这个变量变化。也就是说,如果线程 A 修改了共享变量 V 的值,那么线程 B 在使用 V 的值时,能立即读到 V 的最新值。
能保证内存可见性的两种操作:
加锁
加锁的原理是比如当线程获得锁之后,会清空本地内存,然后从主内存拷贝最新的共享变量,执行代码,执行完之后刷新主内存中共享变量的值,释放锁。
volatile关键字
使用 volatile 修饰共享变量后,每个线程要操作变量时会从主内存中将变量拷贝到本地内存作为副本,当线程操作变量副本并写回主内存后,会通过 CPU 总线嗅探机制告知其他线程该变量副本已经失效,需要重新从主内存中读取。
volatile 保证了不同线程对共享变量操作的可见性,也就是说一个线程修改了 volatile 修饰的变量,当修改后的变量写回主内存时,其他线程能立即看到最新值。
读写锁的用处就在于,当写线程没写完时,可能就会有线程读了,因此加上写锁,写完再释放锁,这时候就能读了,再加上读锁,读完才能继续往里面写。
这时候就有人会问了,那这个锁和volatile关键字有啥区别呢,不都是让共享变量更新的时候立马让其他线程可见么?
我的理解是,volatile只是让共享变量更新完之后能立马更新工作内存和主内存,但在这之前读线程可能会先读,所以需要锁,若没有volatile就算写完了,可能读到的也不是更新的值。
读写锁的演变:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEEBhwgM-1657634160743)(C:\Users\aMyth\AppData\Roaming\Typora\typora-user-images\image-20220706211556728.png)]](/img/b2/5173149c627366c0630af888e0ad45.png)
读写锁的降级
将写入锁降级为读锁
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5wYmizU-1657634160745)(C:\Users\aMyth\AppData\Roaming\Typora\typora-user-images\image-20220706211835744.png)]](/img/45/3332edda8361551d9db07523dad3d6.png)
阻塞队列
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iiIEdopo-1657634160759)(C:\Users\aMyth\AppData\Roaming\Typora\typora-user-images\image-20220706214115214.png)]](/img/14/f1e79ce9173a1a3afb5ecec5161b0a.png)
线程1 往队列中放元素,线程2从中取元素
队列满了 则放的线程阻塞,空的时候取得线程阻塞
它得好处就是这个队列的线程操作都是全自动得,啥时候需要阻塞啥时候需要唤醒不用自己操心
阻塞队列分类
ArrayBlockingQueue
有数组结构组成的有界阻塞队列
LinkedBlockingQueue
由链表结构组成的有(大小默认值为integer.MAX_VALUE)阻塞队列
DelayQueue
使用优先级队列实现的延迟无界阻塞队列
核心方法

边栏推荐
- 【USB Host】STM32H7 CubeMX移植带FreeRTOS的USB Host读取U盘,USBH_Process_OS卡死问题,有个值为0xA5A5A5A5
- jupyter notebook一直自动重启(The kernel appears to have died. It will restart automatically.)
- Xshell远程访问工具
- Points for attention in adding spp module to the network
- HAL_ Delay() delay error about 1ms
- Qt 使用纯代码画图异常
- vscode 多行注释总是会自动展开的问题
- Jupyter notebook选择conda环境
- 【数据库系统原理】第五章 代数和逻辑查询语言:包、扩展操作符、关系逻辑、关系代数与Datalog
- Could not load library cudnn_cnn_infer64_8.dll. Error code 126Please make sure cudnn_cnn_infer64_8.
猜你喜欢

《机器学习》(周志华)第2章 模型选择与评估 笔记 学习心得

《统计学习方法(第2版)》李航 第17章 潜在语义分析 LSA LSI 思维导图笔记 及 课后习题答案(步骤详细)第十七章

信号与系统:希尔伯特变换

删除分类网络预训练权重的的head部分的权重以及修改权重名称
![[USB host] stm32h7 cubemx porting USB host with FreeRTOS to read USB disk, usbh_ Process_ The OS is stuck. There is a value of 0xa5a5a5](/img/be/b7723920f0e81e8699bb26dd1c0fe5.png)
[USB host] stm32h7 cubemx porting USB host with FreeRTOS to read USB disk, usbh_ Process_ The OS is stuck. There is a value of 0xa5a5a5
![[activiti] personal task](/img/bc/80ac4067f6c58785acb4273f9507ee.png)
[activiti] personal task

谷歌/火狐浏览器管理后台新增账号时用户名密码自动填入的问题

String methods and instances
![[deep learning] teach you to write](/img/c6/333b16758d79ebd77185be6e3cb38f.png)
[deep learning] teach you to write "handwritten digit recognition neural network" hand in hand, without using any framework, pure numpy

The problem that the user name and password are automatically filled in when Google / Firefox manages the background new account
随机推荐
[activiti] process example
第三章 线性模型总结
[activiti] group task
读取csv文件的满足条件的行并写入另一个csv中
systemctl + journalctl
Thymeleaf快速入门学习
‘Results do not correspond to current coco set‘
【FatFs】手动移植FatFs,将SRAM虚拟U盘
Machine learning (zhouzhihua) Chapter 5 notes on neural network learning
Raspberry pie is of great use. Use the campus network to build a campus local website
如何在网页上下载视频
找数组中出现次数最多的数
STM32 standard peripheral Library (Standard Library) official website download method, with 2021 latest standard firmware library download link
Numpy array broadcast rule memory method array broadcast broadcast principle broadcast mechanism
js星星打分效果
删除分类网络预训练权重的的head部分的权重以及修改权重名称
jupyter notebook一直自动重启(The kernel appears to have died. It will restart automatically.)
《机器学习》(周志华)第2章 模型选择与评估 笔记 学习心得
[activiti] process variables
[deep learning] teach you to write "handwritten digit recognition neural network" hand in hand, without using any framework, pure numpy