Java并发编程的艺术-Java内存模型

2019-02-24  本文已影响0人  油多坏不了菜

基础

重排序

volatile的内存语义

锁的内存语义

final内存语义

hanppens-before规则

如果A happens before B,那么A的执行结果对B可见。(java中 并不一定表示A比B先执行,如果A与B执行的顺序对结果没有影响是可以重排序的)

双锁检查锁定与延迟初始化

  1. 有问题的demo
private static Instance ins;
public static Instance getInstance(){
if(ins == null){
   synchronized(ins){
    if(ins == null)
      ins = new Insatance();//这一步不是原子操作
  }
}
return ins;

上面问题出在 ins = new Instance()这句不是原子操作,而且其中可能存在重排序,所以 ins变量不为null时,对象可能还没有被初始化.

  1. 基于volatile的解决方案
    对实例字段的延迟初始化
    当把对象声明为 volatile时,可以禁止重排序,保证getInstance()方法返回的对象一定是已经被正确初始化了的。
  2. 基于类初始化的解决方案
    对静态字段的延迟初始化。
public class InstanceFactory{
    private static class InstanceHoler{
      public static Ins = new Instance();
   }
public static Instance getInstance(){
     return InstanceHolder.ins;
 }
}
上一篇 下一篇

猜你喜欢

热点阅读