原来voliate是这样用的

       洪水和暴雨褪去,酷暑如期而来,酷暑侵蚀着整个上海的天气。燥热的天气让想跳槽的心更加跃跃欲试,重新翻翻了周老板的《深入理解Java虚拟机》把自己对voliate的理解重新梳理一下也记录一下。

        现代的计算器多任务处理是一项必须的功能,许多场景下需要计算器同时去处理多件事,这不仅仅是应为计算器的运算能力太强大了,更多的原因是应为计算器的运算速度与它存储和通信子系统的速度差距太大,大量的时间都花费在磁盘I/O、网络通信或者数据库访问上,这时我们不希望处理器大部分时间都处于等待状态,这时多任务就应运而生。处理器在执行任务的时候需要与内存交互、如读取数据、存储运算结果,。由于计算器的存储设备和处理器的运算速度有着几个数量级的差距,所以现代计算机系统中都加入一层或者多层读写速度与处理器运算速度接近的高速缓存来作为内存与处理器之间的缓冲,将运算需要使用的数据复制到缓冲中,让运算快速进行,当运算完成后再从缓存同步到内存中,这样处理器就无须等待缓慢的内存读写了。高速缓存解决了处理内存速度之间的矛盾也带来了新问题:缓存一致性

        java的内存模型所以的变量都存在主存中(虚拟机内存的一部分可以与物理主存类比)。每条线程都有自己的工作内存,可以与处理器的高速缓存类比,工作线程就是保存了被该线程使用中变量的主内存副本。,线程对变量所有逇读写都是在工作内存中进行的,线程之间的变量值传递也都需要通过主存传递。工作内存在完成计算后会将值写会主存中。好说了这么多(抄了这么多) 我们大概了解了处理器是如何工作的了。

voliate特性

现在我们开始进入正题关于voliate关键字,voliate关键字可以说是java轻量级的同步机制。当一个变量定义为voliate后,他将具有两个特性:

第一项保证此变量对所有的线程的可见性,这里的可见性主要是每当线程改变了这个值会在第一时间刷新到主存中去其他线程会在第一时间读取到新值。但是由于每次使用前都要刷新一次,执行引擎得到的一定是最新的,但是java运算符操作是非原子性的因此voliate在并发的情况下运算一样是不安全的。

第二项使用voliate变量是禁止指令重排序优化,普通变量会保证该方法的执行过程所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序和代码中执行顺序一致。比如在指令重排序的优化可能会把代码后面一些的赋值操作优化到前面进行。而加入了voliate关键字相当于增加了一个内存屏障指令重排序的时候不能把后面的指令重排序到内存屏障之前的位置。

voliate可以说是java轻量级的同步机制的同步机制,他的读取性能几乎与普通变量没有什么区别,但是写操作可能会慢上yuixie,因为他需要本地代码中插入需要内存屏障的指令保证处理器不会乱序执行。

参考《深入理解Java虚拟机》

 

posted @ 2020-08-10 10:06  回忆漫长  阅读(1230)  评论(0编辑  收藏  举报