多线程遇到的三个问题:1、原子性 2、可见性 3、有序性
原子性问题最不好解决,因为根源在于线程切换,如果要实现对 a 对象的原子性操作,需要将它所有的操作方式包装隐藏起来,加锁。强制变成单线程操作,才可以解决这个问题
volatile可以很好解决可见性问题,和有序性问题
可见性比较好理解,有序性用起来不是很好理解,比如对 a 对象用volatile修饰,那么在
a = xxx;代码的前后会禁止一些重排列:在代码前面的写操作一定会发生在代码之前,代码之后的读操作一定会发生在代码之后。
最大的作用就是双重检查里面的作用:初始化的时候,能保证 instance != null 的时候,a的内存指向是一个完整的对象内存空间:
禁止 2、3重排序:
memory = allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance = memory; //3:设置instance指向刚分配的内存地址