应用范围:
volatile关键字是对变量进行上锁,锁住的是单个变量,而synchronized还能对方法以及代码块进行上锁。
是否保证原子性:
在多线程环境下,volatile可以保证可见性和有序性,不能保证原子性,而synchronized在保证可见性和有序性的基础上,还可以保证原子性。
volatile变量的原子性与synchronized的原子性是不同的。synchronized的原子性是指,只要声明为synchronized的方法或代码块,在执行上就是原子操作,synchronized能保证被锁住的整个代码块的原子性。而volatile是不修饰方法或代码块的,它只用来修饰变量,对于单个volatile变量的读和写操作都具有原子性,但类似于volatile++这种复合操作不具有原子性。所以volatile的原子性是受限制的。所以,在多线程环境中,volatile并不能保证原子性。
使用场景:
volatile主要用于解决共享变量的数据可见性问题,而synchronized主要用于保证访问数据的同步性(同时也能保证可见性)。
保证有序性的方式:
volatile的有序性是通过禁止指令重排序来实现的。synchronized无法禁止指令重排,但是可以通过单线程机制来保证有序性。由于synchronized修饰的代码,在同一时刻只能被一个线程访问,从根本上避免了多线程的情况。而单线程环境下,在本线程内观察到的所有操作都是天然有序的,所以synchronized可以通过单线程的方式来保证程序的有序性。
性能方面:
volatile是线程同步的轻量级实现,性能高于synchronized。多线程访问volatile修饰的变量时不会发生阻塞(主要是因为volatile采用CAS加锁),而访问synchronized修饰的资源时会发生阻塞。