并发三大特性:
- 原子性:
原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响。可以通过 synchronized和Lock实现原子性,volatile不能保证原子性。 - 有序性:
有序性是指对于单线程的执行代码,我们总是认为代码的执行是按顺序依次执行的,即使指令重排也要保证执行结果不受影响。 - 可见性:
共享变量在不同线程的工作内存可见,volatile可以解决可见性问题(能否及时可见),不加volatile也可能可见,但不一定及时。synchronized和Lock也可以保证可见性,因为它们可以保证任一时刻只有一个线程能访问共享资源,并在其释放锁之前将修改的变量刷新到内存中。
手动添加内存屏障:
使用UnSafe类
UnsafeInstance.reflectGetUnsafe().fullFence();
由于UnSafe类是由启动类加载器加载,只能通过反射获取:
public class UnsafeInstance {
public static Unsafe reflectGetUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
volatile内存语义
volatile可以保证可见性,禁止指令重排序(DCL需要添加volatile)。通过内存屏障实现。