Java中多线程安全问题实例分析
程序猿小军 · 459浏览 · 发布于2020-12-16
案例
package com.duyang.thread.basic.basethread; /** * @author :jiaolian * @date :Created in 2020-12-16 14:02 * @description:线程不安全分析 * @modified By: * 公众号:叫练 */ public class ThreadUnsafe { public static void main(String[] args) { Thread task = new Task(); Thread threadA = new Thread(task,"A"); Thread threadB = new Thread(task,"B"); Thread threadC = new Thread(task,"C"); Thread threadD = new Thread(task,"D"); Thread threadE = new Thread(task,"E"); threadA.start(); threadB.start(); threadC.start(); threadD.start(); threadE.start(); } private static class Task extends Thread { int count = 5; @Override public void run() { /** * jvm分3步骤; * 1.获取count(从主内存获取值) * 2.count减1(在各自寄存器完成) * 3.保存count(刷新到主内存) * * 说下可能执行的过程... * 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 * 情况就是这样的 * */ count--; System.out.println(Thread.currentThread().getName() + " "+count); } } }
可能的结果
结果得到下图(结论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图>的执行过程。
结论
多线程安全一直是个很重要的话题,希望大家都能尽快理解掌握,希望大家喜欢!
相关推荐
PHP实现部分字符隐藏
沙雕mars · 1324浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别
kenrry1992 · 907浏览 · 2019-05-08 21:14:54
5月语言排行榜:R 跌出前二十,Python 紧咬 C++
manongba · 686浏览 · 2019-05-09 17:27:24
Tomcat 下载及安装配置
manongba · 967浏览 · 2019-05-13 21:03:56
什么是SpringBoot
iamitnan · 1086浏览 · 2019-05-14 22:20:36
分类专栏
最新发布
最热排行
0评论