目录

一、什么是线程安全?

二、线程不安全的原因

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上进行执行的

  1. 把内存的数据读取到CPU的寄存器上(load)
  2. 把CPU的寄存器中的值,进行+1(add)
  3. 把寄存器中的值,写回到内存中(save)

这里简单的描述几种情况,初始条件:初始值为1,对其进行两次自增。

Java中的多线程安全问题相关推荐

  1. Web开发基础_Servlet学习_0011_Servlet中的多线程安全问题与Servlet运行原理

    Servlet中的多线程安全问题 Servlet运行原理 Servlet中的多线程安全问题 演示 案例演示: 工程案例目录结构 pom.xml: <project xmlns="htt ...

  2. Java基础——深入理解Java中的多线程(超级详细,值得你看)

    Java中的多线程 进程(process)是程序的一次执行过程,或是正在运行的有一个程序,或是正在运行的一个程序.是一个动态的过程:有它自身的产生.存在和消亡的过程.--生命周期. 线程(thread ...

  3. Java中的多线程编程(超详细总结)

    文章目录 Java中的多线程编程(超详细总结) 一.线程与多线程的概念 二.线程与进程之间的关系 三.一个线程的生命周期 四.多线程的目的和意义 五.线程的实现的方式 Java中的多线程编程(超详细总 ...

  4. JAVA中的多线程(一)

    JAVA中的多线程(一) 进程:是一个正在执行中的程序 每一个进程执行都有一个执行的顺序,该顺序是一个执行路径,或者叫控制单元 线程:就是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中 ...

  5. JAVA中的多线程(八):线程的优先级和yield方法

    JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...

  6. JAVA中的多线程与运动仿真(1)——用JAVA来放一场烟花

    JAVA中的多线程与运动仿真(1)--用JAVA来放一场烟花 一.实现效果的简单展示: 初步实现的动态效果为在鼠标点击之后,点击之处出现一簇小球,然后向不同方向散开变大. 利用这一效果,再在后续增加颜 ...

  7. 草根方式学习java中的多线程

    草根方式学习java中的多线程 下面有具体的代码和截图 源码点这里 多线程即在同一时间,可以做多件事情(说白了,就是齐头并进) 单线程就是按部就班 创建多线程有2种方式,分别是继承线程Thread类, ...

  8. java中实现多线程的三种方式

    java中实现多线程的三种方式 1.实现多线程的方法: 在java中实现多线程的两途径:继承Thread类,实现Runable接口(Callable) 2.继承Thread类实现多线程: ​ 继承类T ...

  9. Java中的多线程基本介绍

    在 Java 中,多线程是指同时执行两个或多个线程以最大限度地利用 CPU 的过程. Java 中的线程是一个轻量级进程,只需要较少的资源即可创建和共享进程资源. 多线程和多进程用于 Java 中的多 ...

最新文章

  1. 彻底理解 Cookie,Session,Token
  2. python与MySQL交互
  3. 90后80后70后60后和50后的无奈
  4. 理工男都能有多痴情?
  5. AngularJS1.5+ 笔记
  6. Linux下C++开发系列(一)序——我是如何开始linux下C++开发的
  7. c++之std::distance()函数
  8. 内存映射过程之paging_init
  9. GB18030:蒙文字符方向为什么转了90度
  10. 龙腾P2P流媒体点播系统商业计划书
  11. MediaType和文件类型对应关系
  12. EXCEL表格-COUNTIF函数查找数据重复项
  13. 计算机辅助翻译和人工翻译的优缺点,计算机辅助翻译的利与弊以及解决方案
  14. 字节跳动全链路压测(Rhino)的实践
  15. [个人资料整理]游戏类型总结
  16. 马士兵网络安全大师班薪选课程
  17. 第2阶段 第12讲 XMLHTTP协议
  18. 流量卡官网源码 有后台带文章系统
  19. 递归算法中的时间复杂度分析
  20. 洞房花烛夜山西人必喝的和气拌汤——西红柿鸡蛋拌汤

热门文章

  1. iOS 多线程使用示例
  2. 【matlab报错问题个人总结】数组超出索引维度
  3. 基于antd pro框架,配置接口apiUrl前缀
  4. 专访许雪松:深入理解嵌入式开发
  5. compat-wireles的理解
  6. 同是数据分析产品, 为什么200万App企业都选择友盟+
  7. VMware 14 Pro 永久许可证激活密钥
  8. 小程序开发特辑—小程序申请及开发环境搭建
  9. 简单谈C++为什么是面向对象的程序设计
  10. WebLogic之WebLogic安装