多线程&高并发深入浅出原子性

Posted Roninaxious

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程&高并发深入浅出原子性相关的知识,希望对你有一定的参考价值。

1.首先如何理解原子性这个概念?

想必都学过化学,在该化学反应中“原子”被称为不可再分割的微粒,而我们并发编程中的“原子性”与该概念类似,指的是某一个操作能否在一个CPU时间段内完成。(要么把该操作相关的指令全都执行完,要不执行

📑能完成最好,那当然不会出现什么问题!
📑如果不能完成,那就可能产生一些问题了

【会发生什么问题呢?】

首先得考虑清除什么情况下会发生原子性问题,单线程会嘛?当然不会,你一个线程又不发生线程切换,就不需要保证操作得原子性。


所以说,只有在多线程环境下,才会出现原子性问题。

看下面代码,使用5个线程各自对a进行1000次的++操作。

public class Atomicity 
 
    private static int a = 0;
    public static void main(String[] args) throws InterruptedException 
        Runnable increment = () -> 
            for (int i = 0; i < 1000; i++) 
                a++;
            
        ;
        for (int i = 0; i < 5; i++) 
            Thread t = new Thread(increment);
            t.start();
        
        TimeUnit.SECONDS.sleep(2);
        System.out.println(a);
    

想必都能猜出结果:

结果有可能是5000也有可能低于5000.

2.从字节码角度分析++操作

public class AddOperation 
    private static int num = 0;

    public void method() 
        num++;
    

对上述代码进行反汇编,结果如下:

getstatic:将类变量num的值取出将其压入操作数栈
iconst_1:将常数1压入操作数栈
iadd:执行一次加法操作(连续弹栈两次,将整型数据相加,并将结果压入操作数栈)
putstatic:将栈顶数据弹出,赋给num

当两个线程对num进行++操作时,会发生什么现象呢?


这就是产生了原子性问题。如何解决呢?(只演示synchronized)

   Runnable increment = () -> 
            synchronized (lock) 
                for (int i = 0; i < 1000; i++) 
                    a++;
                
            
        ;

以上是关于多线程&高并发深入浅出原子性的主要内容,如果未能解决你的问题,请参考以下文章

多线程&高并发深入浅出可见性

高并发多线程安全之原子性问题CAS机制及问题解决方案

并发与高并发-线程安全性-原子性-synchronized

Java高并发编程实战2,原子性可见性有序性,傻傻分不清

聊聊高并发(十九)理解并发编程的几种&quot;性&quot; -- 可见性,有序性,原子性

Java高并发程序设计—— java内存模型和线程安全