美文网首页
Java多线程学习之原子性,可见性、有序性

Java多线程学习之原子性,可见性、有序性

作者: 魂之挽歌w | 来源:发表于2019-09-28 22:47 被阅读0次

前言

  在多线程中,要想并发程序正确地执行,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。下面依次介绍下这三个特性。

概念与理解

原子性:在一个操作中cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。例如:a =0;这个操作就是原子的,无法再拆分了。但a = a +1;就不是原子性的操作了,在实际程序运行过程中,会拆分为:1、从主内存读取a的初始值2、进行a+1操作3、对a重新赋值

可见性:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
举个栗子

//主线程
int a =0;
//线程1
 a =2;
//线程2
b =a +1;

  有变量a,初始值为0,假若执行线程1的是CPU1,执行线程2的是CPU2。由上面的分析可知,当线程1执行 a=2这句时,会先把a的初始值加载到CPU1的高速缓存中,然后赋值为2,那么在CPU1的高速缓存当中i的值变为0了,却没有立即写入到主存当中。
此时线程2执行 b = a,它会先去主存读取a的值并加载到CPU2的缓存当中,注意此时内存当中a的值还是0,那么就会使得b的值为1,而不是3.
这就是可见性问题,线程1对变量a修改了之后,线程2没有立即看到线程1修改的值。

解决:

  Java内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方法来实现可见性的,无论是普通变量还是volatile变量都是如此,普通变量与volatile变量的区别是volatile的特殊规则保证了新值能立即同步到主内存,以及每使用前立即从内存刷新。因为我们可以说volatile保证了线程操作时变量的可见性,而普通变量则不能保证这一点。

有序性:即程序执行的顺序按照代码的先后顺序执行。
看下面代码:

int a =0;
long b =0;
a = 1;  //语句1
b = 2; //语句2

  从代码顺序上看,语句1是在语句2前面的,那么JVM在真正执行这段代码的时候会保证语句1一定会在语句2前面执行吗?不一定,为什么呢?这里可能会发生指令重排序(Instruction Reorder)
下面解释一下什么是指令重排序,一般来说,处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
比如上面的代码中,语句1和语句2谁先执行对最终的程序结果并没有影响,那么就有可能在执行过程中,语句2先执行而语句1后执行。
但是要注意,虽然处理器会对指令进行重排序,但是它会保证程序最终结果会和代码顺序执行结果相同,那么它靠什么保证的呢?再看下面一个例子:

//线程1
int a =0;
bollean b=false;
a = 1;
b = true;
//线性2
while(!b){
sleep()
}
doSomethingWithA(a);

  这个例子只是为了表达一下可见性(实际是有问题的),在线程1中a=1,然后b=true,这两个操作在JVM中完全是可以颠倒顺序的,而线程2中b=ture,退出循环,使用a来做操作,此时a=0,就会发生问题。

参考

相关文章

  • 浅谈java高并发

    JMM JMM是java的内存模型,JMM的关键技术就是围绕着多线程的原子性,可见性,有序性来建立的。 1.原子性...

  • Java-可见性、原子性、有序性

    关键字:Java内存模型(JMM)、线程安全、可见性、原子性、有序性 1.线程安全(JMM) 多线程执行某个操作的...

  • Java高并发--原子性可见性有序性

    Java高并发--原子性可见性有序性 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 原子性:...

  • jvm

    JAVA内存模型: 有序性、可见性、原子性 导致可见性的原因是缓存,导致有序性的原因是编译优化 涉及 vol...

  • volatile和synchronized底层原理

    先来看 JMM java memory model java 内存模型 主要围绕:原子性,可见性,有序性。 A B...

  • Java内存模型&DCL双锁检测

    Java内存模型 内存模型是为了保证共享内存的正确性(可见性、有序性、原子性),其定义了共享内存系统中多线程程序读...

  • 理解java中的Synchronized关键字

    开篇知识了解 插入知识 JMM(java内存模型)的关键技术都是围绕着多线程的原子性,可见性,有序性来建立的。因此...

  • Java 中的volatile 关键字

    并发编程的三个特性 原子性 有序性 可见性 Java 中的volatile 关键字能保证可见性和有序性,但是无法保...

  • java多线程(壹)——线程与锁

    线程与线程安全问题 所有的线程安全问题都可以概况为三个点:原子性,可见性、有序性——————by Java多线程编...

  • Java多线程笔记(一):JMM与基础关键字

    JMM特性一览 Java Memory Model的关键技术点都是围绕着多线程的原子性、可见性和有序性来建立的。因...

网友评论

      本文标题:Java多线程学习之原子性,可见性、有序性

      本文链接:https://www.haomeiwen.com/subject/jiftpctx.html