1.volatile本质是告诉jvm当前工作内存中的值,是不确定的,需要从主存中取,synchronized是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞。
2.volatile仅能使用在变量级别,synchronized则可以使用在变量、方法和类级别。
3.volatile仅能实现变量级别的修改可见性,不能保证原子性;(即单例双重锁写的时候,一个线程创建了这个单例对象,其他线程就会知道,但是多线程共同访问一个成员变量时,volatile表现的是线程不安全,synchronized则可以保证变量的修改可见性和原子性)。
4.volatile不会造成线程阻塞,synchronized可能会造成线程阻塞。
5.对于volatile变量的写会立即刷新到主存,对volatile变量的读会读主存中的新值。
应用volatile变量的三个原则:
(1)写入变量不依赖此变量的值,或者只有一个线程修改此变量
(2)变量的状态不需要与其它变量共同参与不变约束
(3)访问变量不需要加锁
举例:微医需要记录用户(以手机号为维度)最后一次登录的外部用户id,而不同的合作方有不同的外部用户id和四级域名,所以可以对外部用户id用volatile关键字修饰。
public class UserManager { public volatile String lastUserId; public boolean authenticate(String user, String password) { boolean valid = passwordIsValid(userId, password); if (valid) { User u = new User(); activeUsers.add(u); lastUserId= userId; } return valid; } }