volatile关键字
volatile关键字是轻量级的synchronized(严格来说不是轻量级syn),主要就是保证共享变量的可见性,就是一个线程修改一个变量,对其他的线程是可见的。而且volatile可以通过内存屏障防止指令重排序。内存屏障是一条CPU指令,主要用来确保一些特定操作的执行顺序,Java内存模型将在写操作后插入一个写屏障指令,在读操作前插入一个读屏障指令。内存屏障主要分为读读屏障,写写屏障,读写屏障,写读屏障,写读屏障是万能屏障。
volatile的实现有两点,lock前缀指令可以使处理器缓存重写到内存,而且会使得其他处理器的缓存失效
Volatile实现内存可见性是通过store和load指令完成的;对volatile变量执行写操作时,会在写操作后加入一条store指令,强迫线程将最新的值刷新到主内存中;而在读操作时,会加入一条load指令,即强迫从主内存中读入变量的值。
Lock前缀指令作用
volatile读写操作时,会有个Lock前缀指令,它的作用
-
将当前处理器缓存行的数据写回到系统内存。
-
这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。
volatile不是线程安全,因为无法保证操作的原子性,但是可以通过和循环CAS或锁机制联用来促使线程安全。循环CAS保证了操作的原子性,锁机制保证了同一时间只有一个线程在进行。
synchronized关键字
synchronized是重量级锁,它本来是很重的,但是后来引入了偏向锁和轻量级锁,完成了锁的升级,使得获得锁和释放锁的效率大大降低。
synchronized是可重入锁,修饰的静态方法是可重入的,实现的方法可以调用自己
说说 synchronized 关键字和 volatile 关键字的区别
synchronized
关键字和 volatile
关键字是两个互补的存在,而不是对立的存在!
-
volatile
关键字是线程同步的轻量级实现,所以volatile
性能肯定比synchronized
关键字要好。但是volatile
关键字只能用于变量而synchronized
关键字可以修饰方法以及代码块。 -
volatile
关键字能保证数据的可见性,但不能保证数据的原子性。synchronized
关键字两者都能保证。 -
volatile
关键字主要用于解决变量在多个线程之间的可见性,而synchronized
关键字解决的是多个线程之间访问资源的同步性。
synchronized和Lock的区别
-
synchronized是关键字,lock是接口
-
synchronized可以锁代码块和方法,lock只能锁代码块
-
synchronized不可得知是否拿到锁,lock可以得知是否拿到锁
-
synchronized是不可中断的,lock既可以中断也可以不中断
-
synchronized会自动释放锁,lock只能手动释放锁
-
synchronized是非公平锁,lock即可以是非公平锁又可以是公平锁
-
lock有一个读写锁,可以提高效率