原子性:原子操作是不能被线程机制中断的操作;一旦操作开始,那么他一定可以在发生上下文切换之前执行完毕
除了long和double之外的所有基本类型的简单操作都是原子性的。当定义long或double变量时,使用关键字volatile关键字,long和double就会获得原子性。
可视性:一个任务做出的修改,对其他任务可能是否可视,(例如只是暂时存储在本地处理器的缓存中,因此不同的任务对应用的状态有不同的视图)
一个任务做出的修改,即使在不中断的意义上讲是原子性的,对其他任务也可能是不可视的,如果将一个域声明为volatile,那么这个与就确保了可视性,只要对这个域产生写操作,那么所有的读操作都可以看到这个修改。
同步synchronized也可以确保可视性。
volatile并不能对递增不是原子操作这一事实产生影响。 ---如果原本该操作是非原子的,加了volatile后并不会改变他的非原子性
volatile的影响:
①:确保long和double的简单操作是原子性
②:加了volatile可以保证可视性(可视性也可以通过synchronized来保证),加了volatile后可以保证在一个任务修改了这个域的值后,其他任务能立即看到这个修改
原子性和可视性是不同概念,原子性强调的是一个操作是否会被拆分,可视性指的是一个任务对域的修改,另一个任务是否能看到这个修改。这个修改操作是否是原子性的没有关系。
如i++递增操作不是原子性的,递增在微处理器里大概可以分成3条指令,1 取值 2 加操作 3 赋值 这个递增显然不是原子的,某任务做完第3步的赋值操作后,其他任务是否能立即看到这个修改,这是可视性问题。如果声明i是加上volatile,那么做完第3步的赋值操作后,其他任务就能立即看到这个修改,但是加上volatile不会对递增不是原子操作这个事实产生影响,即递增的微操作1 2 3之间是可以被打断的