Java中的多线程安全问题
目录
一、什么是线程安全?
二、线程不安全的原因
2.1 从底层剖析count++的操作
2.2 线程不安全的原因总结
2.3 JVM内存模型(JMM)
三、synchronized 关键字-监视器锁monitor lock
3.1 如何加锁(Synchronized用法和特性)
3.1.1. 独占性
3.1.2 可重入性
四、Java 标准库中的线程安全类
五、volatile关键字
5.1 volatile可以保证内存可见性
5.2 volatile不可以保证原子性
一、什么是线程安全?
简单的理解:如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。
观察一下代码:使用两个线程,每个线程都对这个 Counter进行5w次自增,预计是结果为10w。
/*** Created with IntelliJ IDEA.* Description:* User: 86136* Date: 2023-01-12* Time: 20:50*/
class Counter {public int count = 0;public void increase() {count++;}
}
public class Demo13 {static Counter counter = new Counter();public static void main(String[] args) throws InterruptedException {//使用两个线程,每个线程都对这个 Counter进行5w次自增//预计是结果为10wThread t1 = new Thread(() -> {for (int i = 0; i < 5_0000; i++) {counter.increase();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 5_0000; i++) {counter.increase();}});t1.start();t2.start();t1.join();t2.join();System.out.println(counter.count);}
}
运行结果:
二、线程不安全的原因
上面我们使用了多线程运行了一个程序,想让这个变量从0自增到10w次,但是最终实际结果比我们预期的结果要小,这是线程调度顺序的随机性导致的,造成了线程间自增的指令集交叉,导致本来需要自增两次但值只自增了一次的情况。所以得到的结果偏小。
2.1 从底层剖析count++的操作
count++ 操作,在底层其实是被分为三条指令在CPU上进行执行的
- 把内存的数据读取到CPU的寄存器上(load)
- 把CPU的寄存器中的值,进行+1(add)
- 把寄存器中的值,写回到内存中(save)
这里简单的描述几种情况,初始条件:初始值为1,对其进行两次自增。
Java中的多线程安全问题相关推荐
- Web开发基础_Servlet学习_0011_Servlet中的多线程安全问题与Servlet运行原理
Servlet中的多线程安全问题 Servlet运行原理 Servlet中的多线程安全问题 演示 案例演示: 工程案例目录结构 pom.xml: <project xmlns="htt ...
- Java基础——深入理解Java中的多线程(超级详细,值得你看)
Java中的多线程 进程(process)是程序的一次执行过程,或是正在运行的有一个程序,或是正在运行的一个程序.是一个动态的过程:有它自身的产生.存在和消亡的过程.--生命周期. 线程(thread ...
- Java中的多线程编程(超详细总结)
文章目录 Java中的多线程编程(超详细总结) 一.线程与多线程的概念 二.线程与进程之间的关系 三.一个线程的生命周期 四.多线程的目的和意义 五.线程的实现的方式 Java中的多线程编程(超详细总 ...
- JAVA中的多线程(一)
JAVA中的多线程(一) 进程:是一个正在执行中的程序 每一个进程执行都有一个执行的顺序,该顺序是一个执行路径,或者叫控制单元 线程:就是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中 ...
- JAVA中的多线程(八):线程的优先级和yield方法
JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...
- JAVA中的多线程与运动仿真(1)——用JAVA来放一场烟花
JAVA中的多线程与运动仿真(1)--用JAVA来放一场烟花 一.实现效果的简单展示: 初步实现的动态效果为在鼠标点击之后,点击之处出现一簇小球,然后向不同方向散开变大. 利用这一效果,再在后续增加颜 ...
- 草根方式学习java中的多线程
草根方式学习java中的多线程 下面有具体的代码和截图 源码点这里 多线程即在同一时间,可以做多件事情(说白了,就是齐头并进) 单线程就是按部就班 创建多线程有2种方式,分别是继承线程Thread类, ...
- java中实现多线程的三种方式
java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: 继承类T ...
- Java中的多线程基本介绍
在 Java 中,多线程是指同时执行两个或多个线程以最大限度地利用 CPU 的过程. Java 中的线程是一个轻量级进程,只需要较少的资源即可创建和共享进程资源. 多线程和多进程用于 Java 中的多 ...
最新文章
- 彻底理解 Cookie,Session,Token
- python与MySQL交互
- 90后80后70后60后和50后的无奈
- 理工男都能有多痴情?
- AngularJS1.5+ 笔记
- Linux下C++开发系列(一)序——我是如何开始linux下C++开发的
- c++之std::distance()函数
- 内存映射过程之paging_init
- GB18030:蒙文字符方向为什么转了90度
- 龙腾P2P流媒体点播系统商业计划书
- MediaType和文件类型对应关系
- EXCEL表格-COUNTIF函数查找数据重复项
- 计算机辅助翻译和人工翻译的优缺点,计算机辅助翻译的利与弊以及解决方案
- 字节跳动全链路压测(Rhino)的实践
- [个人资料整理]游戏类型总结
- 马士兵网络安全大师班薪选课程
- 第2阶段 第12讲 XMLHTTP协议
- 流量卡官网源码 有后台带文章系统
- 递归算法中的时间复杂度分析
- 洞房花烛夜山西人必喝的和气拌汤——西红柿鸡蛋拌汤