Java中Volatile关键字能不能保证原子性


今天小编给大家分享一下Java中Volatile关键字能不能保证原子性的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。volatile 是 Java 中的一个相对来说比较重要的关键字,主要就是用来修饰会被不同线程访问和修改的变量。而这个变量只能保证两个特性,一个是保证有序性,另外一个则是保证可见性。那么什么是有序性,什么又是可见性呢?那么什么是有序性呢?其实程序执行的顺序按照代码的先后顺序执行,禁止进行指令重排序。看似理所当然,其实并不是这样,指令重排序是JVM为了优化指令,提高程序运行效率,在不影响单线程程序执行结果的前提下,尽可能地提高并行度。但是在多线程环境下,有些代码的顺序改变,有可能引发逻辑上的不正确。而 volatile 就是因为有这个特性,所以才被大家熟知的。volatile 又是如何保证有序性的呢?有很多小伙伴就说,网上说的是 volatile 可以禁止指令指令重排序,这就保证了代码的程序会严格按照代码的先后顺序执行。这就保证了有序性。被 volatile 修饰的变量的操作,会严格按照代码顺序执行,就是说当代码执行到 volatile 修饰的变量时,其前面的代码一定执行完毕,后面的代码一定没有执行。如果这时候,面试官不再继续深挖下去的话,那么恭喜你,可能这个问题已经回答完了,但是如果面试官继续往下深挖,为什么会禁止指令重排,什么又是指令重排呢?在从源码到指令的执行,一般是分成了三种重排,如图所示: 我们接下来就得看看 volatile 是如何禁止指令重排的。我们直接用代码来进行验证:如果有人看到这段代码,肯定会说,那这段代码出来的结果会是什么呢?有些人说是 2,是的, 如果你只是单线程调用,那结果就是 2,但是如果是多线程调用的时候,最后的输出结果不一定是我们想象到的 2,这时就要把两个变量都设置为 volatile。如果大家对单例模式了解比较多的话,肯定也是关注过这个 volatile,为什么呢免费云主机域名大家看看如下代码:上面的单例模式大家熟悉么?是的,这就是 **双重检查(DCL 懒汉式) **有人会说,因为有指令重排序的存在,双端检索机制也也不一定是线程安全的呀,对呀,所以用到了 synchronized 关键字,让他变成了线程安全的了。其实可见性就是,在多线程环境中,对共享变量的修改对于其他线程是否立即可见的问题。那么他的可见性一般都会表现在什么地方呢?用在什么地方呢?其实一般用这个变量,很多都是为了保证他的可见性,就比如定义的一个全局变量,在其中有个循环来判断这个变量的值,有一个线程修改了这个参数的时候,这个循环会停止,跳转到之后去执行。我们来看看没有使用volatile修饰代码实现:结果大家肯定是可想而知,运行结果肯定是:线程A开始执行:
线程B开始执行
标识已经变更确实,就是这样的。如果我们用 volatile 呢,那么这个代码的执行结果就会不一样呢?我们来试一下:这样我们就能看到另外一个执行结果,在循环当中的输出语句是可以被执行的。也就是说,在线程B 中,我们去修改这个被修饰的变量,那么最终,在线程A中,就能顺利读取到我们的数据信息了。不能,我们来看一点代码,被volatile修饰的变量,如果能够保原子性,那么最终的结果应该是20000,但是每次的最终结果并不能保证就是20000,比如:main final number result = 17114
main final number result = 20000
main final number result = 19317三次执行,都是不同的结果,为什么会出现这种呢?这就和number++有关系了number++被拆分成3个指令执行GETFIELD拿到主内存中的原始值number执行IADD进行加1操作执行PUTFIELD把工作内存中的值写回主内存中当多个线程并发执行PUTFIELD指令的时候,会出现写回主内存覆盖问题,所以才会导致最终结果不为 20000,所以 volatile 不能保证原子性。以上就是“Java中Volatile关键字能不能保证原子性”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注百云主机行业资讯频道。

相关推荐: Bootstrap是不是web容器

这篇“Bootstrap是不是web容器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一免费云主机域名起来看看这篇“Bootstrap是不是web容器”文章吧。…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 03/31 10:57
Next 03/31 11:04

相关推荐