并发编程-发布与逃逸

1.发布与逃逸
1.1 发布对象

发布的意思是是一个对象能够被当前范围之外的代码所使用

在这里插入图片描述

1.2 不安全发布

在这里插入图片描述

1.3 对象溢出

一种错误的发布,当一个对象还没有构造完成时,就使它被其他线程所见

在这里插入图片描述

逃逸带来的问题

在这里插入图片描述

2. 安全发布对象的4种方法

2.1安全发布对象

在静态初始化函数中初始化一个对象引用

将对象的引用保存到volatile类型的域或者AtomicReference对象中(利用volatile happen-before规则)

将对象的引用保存到某个正确构造对象的final类型域中(初始化安全性)

将对象的引用保存到一个由锁保护的域中(读写都上锁)

第一种:静态初始化构造单利

public class StaticDemo {
    private StaticDemo(){}
    private static StaticDemo instance = new StaticDemo();
    private static StaticDemo getInstance(){
        return instance;//当静态构造方法初始化加载的时候
        //一定是安全发布的,但是不保证后续操作这个instance的安全
    }
}

第二种:final域

public class FinalDemo {
   private final Map<String,String> states;
   public FinalDemo(){
       states = new HashMap<>();
       states.put("yojofly","yojofly");
   }
}

第三种:volatile

//第一种单利模式,此时当多线程访问时候,可能存在instance == null都判断成功,返回多个实例的情况

public class VolatileDemo { 
    public VolatileDemo(){}
    private static VolatileDemo instance;
    public static VolatileDemo getInstance(){
        if (instance == null){
                    instance = new VolatileDemo();
                    return instance;
                }
        return instance;
    }
}

//第二种单利模式,为了方式上述问题,我们可以给getInstance方法加锁,或者代码块加锁

public class VolatileDemo {
    public VolatileDemo(){}
    private static VolatileDemo instance;
    public static VolatileDemo getInstance(){
        if (instance == null){
            synchronized (VolatileDemo.class){
               if (instance == null){
                    instance = new VolatileDemo();
                    return instance;
                }
            }
        }
        return instance;
    }
}

上述代码加if (instance == null)的原因是,在第一次获取到为null的基础上,再做一次加锁,做判断,消除掉多线程获取if (instance == null)产生的结果相同的问题,但是在java层面

instance = new VolatileDemo();

是一句话,但是在jvm层面,这句话会被编译成多个指令

例如:指令 m,n,p,那么m,n,p指令的执行顺序一定是顺序执行的吗,此时依然存在指令重排序问题

第三种方法:volatile关键字

public class VolatileDemo {
    public VolatileDemo(){}
    private volatile static VolatileDemo instance;  //给发布对象加上volatile关键字,防止指令重排序
    public static VolatileDemo getInstance(){
        if (instance == null){
            synchronized (VolatileDemo.class){
                if (instance == null){
                    instance = new VolatileDemo();
                    return instance;
                }
            }
        }
        return instance;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值