理解线程安全首先得从两个方面开始:执行控制和内存可见
执行控制的目的是控制代码的执行顺序以及是否可以并发执行。
内存可见控制的是线程执行过程中的内存变量对于其它线程是否可见。
一.volatile关键字解决的是内存可见性问题(在任何线程中volatile修饰的变量都是同步更新的,不存在线程间值不一致)
要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下:
从图中可以看出:
①每个线程都有一个自己的本地内存空间--线程栈空间???线程执行时,先把变量从主内存读取到线程自己的本地内存空间,然后再对该变量进行操作
②对该变量操作完后,在某个时间再把变量刷新回主内存
volatile常用于修饰变量,且该变量能够在不同线程间共享,保证每次读到的volatile变量都是最新的修改值,但是该变量不具有原子性
二,volatile 与 synchronized 的比较
synchronized解决的是执行控制问题。synchronized关键字修饰的代码每次只能被一个线程所访问,同时会创建内存屏障,保证代码中的所有操作都会直接刷入到内存中,而不会出现线程间结果不一致。
①volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法;一个是变量级,一个是类级
②volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。
synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。(具有锁机制、原子性、可同步)