首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

volatile与Java内存模型

前言

Java内存模型都是围绕着原子性、有序性和可见性展开的。为了在适当的场合,确保线程间的有序性、可见性和原子性。Java使用了一些特殊的操作或者关键字来声明、告诉虚拟机,在这个地方,要尤其注意,不能随意变动优化目标指令。关键字volatile就是其中之一。

Java内存模型

1.原子性(Atomicity )

原子性是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

2.可见性(Visibility)

可见性是指一个线程修改了某一个共享变量的值时,其他线程是否能够立即知道这个修改。显然,对于串行程序来说,可见性问题是不存在的。因为你在任何一个找找步骤中修改某个变量,在后续的步骤中读取这个变量的值时,读取的一定是修改后的新值。

3.有序性(Ordering)

对于一个线程的执行代码而言,我们总是习惯性地认为代码是从前往后依次执行的。这么理解也不能说完全错误,因为就一个线程而言,确实会表现成这样。但是,在并发时,程序的执行可能就会出现乱序。给人的直观感受是:写在前面的代码,会在后面执行。听起来有些不可思议,是吗?有序性问题的原因是程序在执行时,可能会进行指令重排,重排后的指令与原指令的顺序未必一致。

volatile

如果你查阅英文字段有关volatile的解释,你会得到最常用的解释是“易变的、不稳定的”。这也正是使用volatile的语义。

当你用关键字volatile声明一个变量时,就等于告诉了虚拟机,这个变量极有可能会被某些程序或者线程修改。为了确保这个变量被修改后,应用程序范围内的所有线程都能够”看到”这个改动,虚拟机就必须采用一些特殊的手段,保证这个变量的可见性等特点。

z比如,根据编译器的优化规则,如果不使用关键字volatile声明变量,那么这个变量被修改后,其他线程可能并不会被通知到,甚至在别的线程中,看到变量的修改顺序都会是反的。一旦使用关键字volatile,虚拟机就会特别小心地处理这种情况。

关键字volatile并不能代替锁,它也无法保证一些复合操作的原子性。比如下面的例子,通过关键字volatile是无法保证i++的原子性操作的

执行上述代码,如果第7行i++是原子性的,那么最终的值应该是100000。但实际上,上述代码的蔬菜总是会小于100000。

此外,关键字volatile也能保证数据的可见性和有序性。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200926A051QS00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券