您好、欢迎来到现金彩票网!
当前位置:2019跑狗图高清彩图 > 先行指令站 >

volatile引发的一系列血案

发布时间:2019-07-07 18:06 来源:未知 编辑:admin

  最早读《深入理解java虚拟机》对于volatile部分就没有读明白,最近重新拿来研究并记录一些理解

  先看一下上面这张图片,即Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存

  那么JMM为何要如此设计?其主要原因有两点:1、达到各平台访问内存效果的一致性 2、提升数据访问速度

  对于提升数据访问速度,主要用到了CPU高速缓存这部分内容:计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存

  比如i++,JVM指令包括3个操作:读取x的值,进行加1操作,写入新的值,如果并发执行i++,可能这三步操作不同线程会穿插执行,原子性就是指,任何一个线程运行这三个操作时,其他线程不能进入运行这三步操作

  每个线程都有各自的工作内存(高速缓存、详见JMM),线程A更改了变量的值后,线程B从自己的工作内存中获取变量的值还可能是A修改前的值

  先看下什么是指令重排:处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的,重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。如果程序不满足先行发生原则,那么可能发生指令重排

  从上面的三个问题来看volatile只能解决:可见性问题、有序性问题,但无法解决原子性问题,原子性问题仍需要锁的手段才能解决

  先行发生原则(Happens-Before)是判断数据是否存在竞争、线程是否安全的主要依据,先行发生原则,可以帮你判定是否并发安全的,从而不必去猜测是否是线程安全了

  下面是Java内存模型中一些“天然的”先行发生关系,这些先行发生关系无需任何同步协助器协作java自带这些规则,可以直接在编码中使用。如果两个关系不在此列,而又无法通过这些关系推导出来,它们的顺序就无法保证,虚拟机可以对它们任意重排序

  程序次序规则: 同一个线程内,按照代码出现的顺序,前面的代码 happens-before 后面的代码,准确的说是控制流顺序,因为要考虑到分支和循环结构。

  管程锁定规则: 对于一个监视器锁的unLock操作 happens-before 于每个后续对同一监视器锁的Lock操作。

  线程启动规则: 在同一个线程里,对Thread.start的调用会 happens-before 于每一个启动线程中的动作。

  一段程序代码的执行在单个线程中看起来是有序的。虽然这条规则中提到“书写在前面的操作先行发生于书写在后面的操作”,这个应该是程序看起来执行的顺序是按照代码顺序执行的,因为虚拟机可能会对程序代码进行指令重排序。虽然进行重排序,但是最终执行的结果是与程序顺序执行的结果一致的,它只会对不存在数据依赖性的指令进行重排序。因此,在单个线程中,程序执行看起来是有序执行的,这一点要注意理解。事实上,这个规则是用来保证程序在单线程中执行结果的正确性,但无法保证程序在多线程中执行的正确性。

  一个unlock操作先行发生于后面(时间上)对同一个锁的lock操作,也就是说无论在单线程中还是多线程中,同一个锁如果出于被锁定的状态,那么必须先对锁进行了释放操作,后面才能继续进行lock操作

  对一个volatile变量的写操作先行发生于后面(时间上)对这个变量的读操作,如果线写入了volatile变量v,接着线读取了v,那么,线写入v及之前的写操作都对线可见(线和线可以是同一个线程),可以看成是volatile解决可见性问题的描述

  使用volatile有了以上知识储备我们来看一下volatile如何正确的使用

  因为可见性保证了volatile多读单写的能力,但又因为volatile没有解决原子性问题的能力,所以不是多读多写

  发个牢骚:这个单例写法真的太矫情了,另外这种懒汉模式double-check写法演化问题分析详见:

http://deafbook.net/xianxingzhilingzhan/293.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有