java 多线程下的原子操作了解认识

public class Test {
    
    boolean flag= false;

    public void changeFlag(){
        flag = true;
    }

    public void execute(){
        if(flag){
            System.out.println("execute....");
        }
    }
}

首先看上述代码:很简单,但是在这里如果有:线程A执行changeFlag方法之后,线程B再执行execute方法,试问,execute方法会不会打印出:execute....呢?  (是的,这个是多线程的案例,由他来引入;)

答案是:不一定会;

原因:

一般情况下,会执行打印的方法,就说说不会打印的理由,

线程A在执行完flag = true;之后,还未完全退出线程A,这时线程B抢到CUP资源,开始执行execute方法,判断flag的值时,flag的值依然为false;

因为在java内存模型中,多线程之间的变量值是不可见的;每个线程都有自己独立的working memory(工作内存),里面保存该线程使用到的变量的副本;程序在执行之前,所有变量都存在主内存当中,线程内存会往主内存中拷贝一份变量的副本,线程执行结束后,会将副本变量值赋给主内存中对应的变量,然后主内存再将修改后的变量赋值到每个线程的副本中;所以线程之间变量值的传递需要通过主内存完成;而线程之间的变量(全局)是不能互相访问的;

回到当前实例,所以这就是线程A中的flag为false的原因;

在这里涉及到java内存模型知识;针对上述例子大致说说原因,推荐链接:https://www.cnblogs.com/rocomp/p/4780532.html

通过上述例子余留了一个问题:如何才能使得线程之间的变量(全局)可见?

java语言支持可见性的实现方法:

synchronize、volatile、final

这里主要说说volatile:

如果在上述例子中flag声明前加上volatile;那么答案就是肯定的了;

但是volatile就可以万能了?当然不是:如下例子:

public class Test{

    public volatile int i=0;

    public void test1(){
        for(i;i<1000;i++){
            system.out.println(i);
        }
    }
}

上述代码,在多线程运行该方法的情况下,是否会打印到1000呢,如果不会可以加到10000或更大,然后让线程睡三秒,执行结果却不是我们想要的(1.到1000依次打印);

打印结果坑定少于1000,那么为什么会出现此问题呢?

这里就是原子操作的原因:For Example 例如:

以下多线程对int型变量x的操作,哪几个需要进行同步:( )
A. x=y; B. x++; C. ++x; D. x=1;

博文转载:https://blog.csdn.net/encoder1234/article/details/52228224

看了上面的链接博文后,是否明白原因了呢?  是的,上述答案除了D外,全是;

volatile虽然在线程之间变量有可见性,但是却并没有保证原子操作;

假如x是一个long或者double类型,且当前系统是32位的,那么,D选项也需要同步;

java对long和double的赋值操作是非原子操作!!long和double占用的字节数都是8,也就是64bits。在32位操作系统上对64位的数据的读写要分两步完成,每一步取32位数据。这样对double和long的赋值操作就会有问题:如果有两个线程同时写一个变量内存,一个进程写低32位,而另一个写高32位,这样将导致获取的64位数据是失效的数据。因此需要使用volatile关键字来防止此类现象。volatile本身不保证获取和设置操作的原子性,仅仅保持修改的可见性。但是java的内存模型保证声明为volatile的long和double变量的get和set操作是原子的。

那么怎样才能让全局变量既方便又安全呢?

请关注:CAS

推荐CAS博文:

https://www.jianshu.com/p/efb2024808a0

http://www.blogjava.net/xylz/archive/2010/07/04/325206.html

推荐volatile博文:

https://www.cnblogs.com/chengxiao/p/6528109.html

https://www.cnblogs.com/zhengbin/p/5654805.html

猜你喜欢

转载自blog.csdn.net/yang1076180972/article/details/83750155