Java中多线程安全问题实例分析
2024-09-24 02:49:59
案例
1 package com.duyang.thread.basic.basethread;
2
3 /**
4 * @author :jiaolian
5 * @date :Created in 2020-12-16 14:02
6 * @description:线程不安全分析
7 * @modified By:
8 * 公众号:叫练
9 */
10 public class ThreadUnsafe {
11
12 public static void main(String[] args) {
13 Thread task = new Task();
14 Thread threadA = new Thread(task,"A");
15 Thread threadB = new Thread(task,"B");
16 Thread threadC = new Thread(task,"C");
17 Thread threadD = new Thread(task,"D");
18 Thread threadE = new Thread(task,"E");
19 threadA.start();
20 threadB.start();
21 threadC.start();
22 threadD.start();
23 threadE.start();
24 }
25
26 private static class Task extends Thread {
27
28 int count = 5;
29 @Override
30 public void run() {
31 /**
32 * jvm分3步骤;
33 * 1.获取count(从主内存获取值)
34 * 2.count减1(在各自寄存器完成)
35 * 3.保存count(刷新到主内存)
36 *
37 * 说下可能执行的过程...
38 * A线程获取cpu的count值为5,A线程先减去1,保存count值为4刷新到主内存,此时还没有执行System.out.println count
39 * 切换到B线程,此时B线程的count值为4,因为B线程是从主内存取的,B线程count值减去1为3,此时刷新到主内存,主内存值变为3
40 * 切换到A线程,执行System.out.println count=3
41 * 切换到B线程,执行System.out.println count=3
42 * 情况就是这样的
43 *
44 */
45 count--;
46 System.out.println(Thread.currentThread().getName() + " "+count);
47 }
48 }
49 }
可能的结果
结果得到下图(结论1图)
按理说应该是这样的啊
对,你想的没错,但是线程A,B的count值都等于3也是有可能的,下面我们来分析下。
详细分析
对于代码中45行,i--其实在JVM中,其实可以分为3步。
- 获取count值(从主内存获取值)
- count减1(在各自寄存器完成)
- 保存count(刷新到主内存)
详细说下A,B实际上在机器中过程
- A线程获取cpu的count值为5,A线程先减去1,保存count值为4刷新到主内存,此时还没有执行System.out.println打印count值。如下图所示
- 切换到B线程,此时B线程的count值为4,因为B线程是从主内存取的,B线程count值减去1为3,此时刷新到主内存,主内存值变为3
- 切换到A线程,执行System.out.println count=3
- 切换到B线程,执行System.out.println count=3
- C D E线程正常执行
这就是<结论1图>的执行过程。
结论
多线程安全一直是个很重要的话题,希望大家都能尽快理解掌握,希望大家喜欢!
我是叫练,多叫多练,欢迎大家和我一起讨论交流,我会尽快回复大家,喜欢点赞哦。
- 清除所有标记
- 清除选中的标记
- 错误类型
- 无错字 - 写作(在线版)
最新文章
- webapi - 使用依赖注入
- ES6新特性概览
- centos 6.4 getmail 收取163 邮件
- proxy改变this指向
- Asp.net 执行回调操作后 无法更新ViewState的问题
- spring与mysql整合数据源的配置
- python3 sys模块
- Java中数据类型默认转换和强制类型转换
- Collection接口中方法的使用
- one by one 项目 part 3
- testlink问题--linux环境下
- 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存
- QQ窗体的控制,同步异步打开360网盘,控制360网盘窗体的移动
- js鼠标触发事件集合
- Light oj 1379 -- 最短路
- C# 笔记——数据类型
- Django-内置Admin
- php与js的crc32(支持中文)
- LVS + KEEPALIVED + WINDOWS SERVER 2008 R2 ------高可用负载均衡(转)
- Zookeeper用来干什么?