ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java-Volatile

2022-05-06 09:31:06  阅读:186  来源: 互联网

标签:volatile Java synchronized 关键字 屏障 线程 内存 Volatile


前序:JUC,java并行编程中的三个特性

1、原子性:一个或多个操作为一个整体,要么整体执行,要么不执行。synchronized保证代码片段的原子性。

2、可见性:当多个线程共享同一个变量时,若其中一个线程对线程进行了修改,那么该修改对其他线程是可见的。volatile保证变量的可见性

3、有序性:程序执行的顺序和代码的先后顺序是相同的。volatile保证禁止指令的重排优化。

 

一、Volatile底层原理(主要还是内存屏障)

1、写屏障,通知处理器将写屏障之前的所有已经存储在存储缓存中的数据同步到主内存。

2、读屏障,配合写屏障,使得写屏障之前的内存更新对于读屏障之后的读操作是可见的。

可见性:

写屏障会保证屏障之前的对共享变量的改动,同步到主存中。

读屏障会保证屏障之后的对共享变量的读取,读取的都是主存中的最新数据。

有序性:

写屏障:会确保指令重排时,不会将写屏障之前的代码排在屏障之后。

读屏障:会确保指令重排时,不会将读屏障之后的代码排在屏障之前。

 

二、JMM(Java 内存模型)

1、java内存模型抽象了线程和主内存的关系,比如线程之间的共享变量必须存储在主内存中。

java内存模型的目的是为了屏蔽系统和硬件的差异,避免一套代码在不同平台下产生效果不同。

jdk1.2之前实现总是从主存中读取变量,是不需要特别的注意的。

而在当前的java内存模型中,线程可以把变量存放在本地内存(机器的寄存器),而不是直接进行在主存中的读写。

这就可能造成一个线程在主存中修改一个变量的值,而另一个线程还在继续使用它在寄存器中的拷贝,造成数据不一致。

 

 

 解决方案:需要把变量为volatile,这就指示JVM,这个变量是共享且不稳定的,每次使用它都到主存中进行读取。

 

 

volatile关键字和synchronized关键字的区别(两个关键字是互补存在的)

1、volatile关键字是线程同步的轻量级实现,所以volatile的性能肯定是比 synchronized关键字要好。

但是volatile关键字只能用于变量,而synchronized关键字可以修饰方法以及代码块。

2、volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字能保证数据的可见性和原子性。(可见性:volatile同样可以保证)。

3、volatile关键字主要用于解决变量在多线程之间的可见性,而synchronized关键字解决的多个线程之间访问的同步性。

4、volatile不会造成线程阻塞,synchronized保证线程的阻塞。

5、volatile关键字主要解决变量在多个线程之间的可见性,而synchronized关键字解决的是多个线程之间的资源同步性。

volatile满足可见性、有序性

synchronized保证可见性、原子性、有序性。

 

标签:volatile,Java,synchronized,关键字,屏障,线程,内存,Volatile
来源: https://www.cnblogs.com/Alei777/p/16227392.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有