关于多线程:Java中多线程安全问题实例分析

8次阅读

共计 1402 个字符,预计需要花费 4 分钟才能阅读完成。

案例


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 图 > 的执行过程。

论断


多线程平安始终是个很重要的话题,心愿大家都能尽快了解把握,心愿大家喜爱!

我是叫练,多叫多练,欢送大家和我一起探讨交换,我会尽快回复大家,喜爱点赞哦。

正文完
 0