| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 深入理解volatile(Java) -> 正文阅读 |
|
[Java知识库]深入理解volatile(Java) |
作者:recommend-item-box type_blog clearfix |
前言除了上篇文章讲到的关键字synchronize关键字外可以实现同步外,java中还有另一个关键字volatile可以实现一些简单的同步。 定义volatile是一个特征修饰符.volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。其在许多语言中都有应用,在java中是一个关键字,其作用主要有以下两点:
下面我们谈谈volatile实现上述功能的原理,为了更好的理解,我们先讲解volatile如何让禁止指令重排序。 volatile与指令重排序首先我们了解下指令重排序的概念。 指令重排序大家有没有想过,我们编写的java代码,机器在执行的时候一定按我们编写的顺序一条一条执行吗?答案是否定的,因为我们编写的代码顺序很可能不是机器cpu执行较优的顺序,因此java内存模型允许编译器和处理器对在编译器或运行时对指令重排序以提高性能,并且只会对不存在的数据依懒性的指令进行重排序。 虽然指令排序能提高性能,但不代表所有的语句都会进行指令重排序,上面也说了指令间需要不存在数据依赖性,数据依赖性有以下3种类型: | 类型 |代码举例 |说明| 听起来指令重排序能提高性能,岂不妙哉,但与此同时也会带来一些问题,很容易想到在多线程情况下,会出现由于指令重排序导致一些非预期结果的出现。 可见性我们首先看看下面的例子来理解变量对所有线程的可见性,我们定义了一个类变量num初始值为0,使用addNum()对num加1,当我们开启N个线程(n>2)去执行addNum(),发现结果num的值并不一定等于N,当调大N时可以明显感知到结果很可能小于N。
运行结果不等于N的原因,是因为num++并不是一个原子操作,反编译后可以看到i++的执行指令如下:
通过上面指令解释大概可以猜测问题出现指令getstatic上,线程获取num值时,没有获取到num被其他线程修改后的最新值,导致最终结果不一致,这里面原因与java内存模型JMM有关,JMM中规定所有的变量都存储在主内存(Main Memory)中,每条线程都有自己的工作内存(Work Memory),线程的工作内存中保存了该线程所使用的变量的从主内存中拷贝的副本。线程对于变量的读、写都必须在工作内存中进行,而不能直接读、写主内存中的变量。同时,本线程的工作内存的变量也无法被其他线程直接访问,必须通过主内存完成。
而当我们给变量num加上volatile后,便可以解决此问题,这是因为当对volatile变量执行写操作后,JMM会把工作内存中的最新变量值强制刷新到主内存,并且写操作会导致其他线程中的缓存无效。使得其他线程从主存中获取到volatile变量的最新值。 volatile为什么没有原子性volatile保证了读写一致性。但是当线程2已经使用旧值完成了运算指令,且将要回写到内存时,是不能保证原子性的。
volatile读写性能volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。 结语本文介绍了volatile的作用,主要有可见性与禁止指令重排两大作用,以及其具备可见性的原因,至于如何实现禁止指令重排序,未作详细介绍,涉及到Java代码、字节码、Jdk源码、汇编层面、硬件层面等底层实现,有兴趣可自行查阅资料了解。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 4:30:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |