本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
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图)

image.png

按理说应该是这样的啊

image.png

对,你想的没错,但是线程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值。如下图所示

image.png

  • 切换到B线程,此时B线程的count值为4,因为B线程是从主内存取的,B线程count值减去1为3,此时刷新到主内存,主内存值变为3

image.png

  • 切换到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
Tomcat 下载及安装配置

manongba · 967浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 961浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1086浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
我是来自差了一点掉完头发的程序猿,小军,希望在这里可以向各位大佬们学习。
分类专栏
小鸟云服务器
扫码进入手机网页