【JavaSE】多线程volatile关键字

编译优化

       我们都知道,所有的高级程序设计语言所编写的源代码,都要经过编译系统或解释系统的翻译,转换为计算机硬件系统能够识别的机器语言代码,才能最终在计算机上执行。
       而现代的编译或解释软件都很强大,很智能,它们会尽可能选择能让我们的程序以最高效率的形式工作,即,它们会尽可能地“优化”我们的代码,使得最终编译或解释出的机器语言代码与我们的源代码有所差异!
       这里要涉及计算机存储体系的概念。

计算机存储体系

       计算机体统有包括外存、内存等不同的存储层次,相对完整地说。计算机存储体系从“外”到“内”分为5层:
               海量外存——存储空间最大,速度最慢;
               外存——存储空间大,速度也比较慢;
               内存——存储空间不是很大,速度却很快;
               高速缓存——存储空间小得多,速度更快;
               寄存器——存储空间最小,速度最快;
        其实,寄存器已经是CPU的范畴了,它们是CPU不可或缺的组成部分。
        在上述存储方式中,最快的是寄存器(组),是CPU指令访问的常客,但是,存储容量非常的少:内存是计算机指令与数据存储的最主要的空间,CPU可以访问内存,但与寄存器比较,对内存的访问速度要慢很多很多。
        我们所编写的程序中,变量、数组的本质就是内存空间(无论是系统堆栈还是系统堆),对变量、数组元素的访问,就是对内存的访问。
        对于像循环中的控制量

for(int i = 0;i < 10;i++)

中的变量i,会在程序中被频繁访问!
        如果每次对变量i的访问,都要执行从内存中“读”或向内存中“写”的话,程序的执行效率会因为内存访问速度很慢,而大打折扣!

变量的寄存器优化

        事实上。很多编译软件都对“要频繁访问的变量”,进行寄存器优化!
        也就是说,对于这个变量,编译系统在第一次访问它的时候,将其从内存中读出,并用一个专门的寄存器保存其值。
        在以后对这个变量进行写(i++)和读(i < 10)时,不是真正地写或读内存中i所代表的空间的值,而是直接对上述的寄存器进行操作!
        也就是说,当编译系统对某个变量进行寄存器优化后,对于这个变量的读、写操作,不是对真正的内存变量空间进行读、写操作,而是仅仅对提取了这个变量数据的寄存器进行操作!
        这意味着,如果存在两个线程,它们都存在对同一变量的寄存器优化后,那么两个线程表面上是对同一变量进行访问,但事实上,却是对各自的寄存器中的值进行访问!(每个线程都会有自己的寄存器,比如,A方法要频繁操作某个private成员,B方法也要频繁操作这个private成员,那么,两个寄存器都会对这个成员进行寄存器优化,为了防止出现多线程并发访问的问题,就需要对这个成员注明:不能进行寄存器优化(volatile)。)
        也就是说,就算某个线程更改了“同一个变量”的值,而其本质知识更改了寄存器的值,而没有真正更改“内存空间“”的值,从而使得两个线程并没有彼此真正相互影响!
        为了避免这样的事故,需要用到 C 和 java 都有的一个关键字,volatile。

volatile关键字

        volatile 关键字用在变量前,像编译器说明:这个变量不能进行寄存器优化!
        也就是说,带有 volatile 关键字修饰的变量,程序中对它的访问语句,在被变量的访问(读/写),一定会坚持对其内存空间进行访问!
        这就可以避免因为变量的寄存器优化所带来的困扰了!
        但是,volatile 关键字也是有代价的!
        很明显,volatile 要求每次对相关变量的访问都必须对其内存空间操作,这将降低程序执行效率!所以,volatile关键字的使用不能“泛滥”!
        如果类的某个成员,会在不同的线程中进行访问,而这种访问“应该”对线程彼此产生影响(使线程通过这个变量关联起来),那么,这个变量最好加上 volatile 修饰!
        还需要进一步说明的是:对于局部变量(包括方法/函数的形参变量),因为使用的是系统堆栈空间,而且,只有在方法/函数被调用的时候才会“申请”它们的空间。
        因此,就算是不同线程执行相同的方法/函数,这些变量也是“线程独立”,即,每一个线程拥有专属于自己的局部变量,对这些变量的更改,不会影响到其它线程的同名变量!
        所以, 局部变量(包括形参变量)是线程安全的! 它们不需要 volatile 关键字修饰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值