Java中的vloatile关键字

藏宝库编辑 2024-9-27 19:54:15 81 0 来自 中国
1 volatile是什么?
它是Java提供的一种轻量级的同步机制。与synchronized修饰方法,代码块差别,volatile只用来修饰变量。而且与synchronized,Lock等重量级锁差别的是,volatile更轻量级,由于它不会引起线程上下文的切换和调理。
2 volatile作用
我们知道并发编程的三大特性:原子性,可见性,有序性。
原子性:
即一个大概多个利用作为一个团体,要么全部实验,要么都不实验,而且利用在实验过程中不会被线程调理机制打断;而这种利用一旦开始,就不绝运行到竣事,中心不会有任何上下文切换。
可见性:
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程可以或许立即看得到修改的值。
有序性:
为了提高步调的实验服从,编译器对编译后的指令举行重排序,即代码的编写顺序不肯定就是代码的实验顺序。
并发编程只有同时满意这三大特性,才气包管步调正确的实验,而volatile只包管了可见性和有序性,不包管原子性。
volatile的作用只有两个:
2.1 保存内存的可见性
2.2 克制JVM内存重排序(包管有序性)
在并发多线程情况下,为什么会有可见性标题?如果不做控制,为什么一个线程修改了共享变量的值,其他线程不能立即看到。这里就必要相识JMM(JAVA内存模子,JAVA memory model)
由于JAVA共享变量是存储在主内存中,而JAVA线程是无法直接访问主内存数据,只能把主内存的数据拷贝一份副本,修改完本地内存的数据,再写回主内存,而此时另一个线程也把主内存的数据拷贝到本身私有的本地内存中,固然线程1已经修改了主内存数据,但线程2却无法感知到,以是就出现了内存可见性标题。
3 可见性实现原理:
当一个共享变量声明为volatile后,会有以下效果:
3.1 当写一个volatile变量时,JMM会把该线程对应的本地内存中的变量强制革新到主内存中去。
3.2 这个写回利用会导致其他线程的缓存无效。
(volatile重要通过汇编lock前缀指令,它会锁定当前内存地域的缓存行,而且立即将当前缓存行数据写入到主内存中耗时非常短),回写主内存的时间会通过MESI协议使其他线程缓存了该变量的所在失效,从而导致其他线程必要去主内存中重新读取数据到工作线程中。)
有序性包管的原理:
它是通过插入内存屏蔽,在内存屏蔽前后克制重排序优化,以此实现有序性。
4 volatile应用场景:
它可以包管可见性和有序性,但无法包管原子性,以是它的应用场景不如synchronized广泛,重要有两个场景:一个是做状态变量,二是做必要重新赋值的共享对象。
 状态变量 这是在java项目中实验的,如果去掉volatile修饰的话,那么就不会打印Thread1担当到了修改的值flag这句话。
2.jpg 但是如果放在安卓demo中,纵然不消vloatile也能关照其他线程(没搞明确为什么详细再实践下实验下)。
5 vloatile与synchronized的区别:
volatile只能修饰变量,而后者可以修饰方法,语句块。
vllatile不能包管原子性,而后者是可以包管原子性的。
都可以包管可见性,但原理差别,Volatile是对变量加了Lock,而后者利用monitorEnter和monitorExit 
volatile不会引起壅闭,而后者会。
在一些场景下利用volatile性能是要更好地。
6 volatile利用条件:
对变量的写利用不依赖当前值:比如i++利用,变量的写利用依赖安全值,以是不能包管线程安全。
该变量没有包罗在具有其他变量的稳定式中。比如i<value,纵然i变量声明为volatile,也不能包管线程安全,由于value大概在运行时间的判定发生变革。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 00:13, Processed in 0.175486 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表