zoukankan      html  css  js  c++  java
  • 单例模式的双检锁的隐患和优化

      摘录加总结------

    (1)传统的单例模式的双检锁

    public class Singleton {
        private static Singleton sInstance;
        public static Singleton getInstance() {
            if (sInstance == null) {//①  
                synchronized (Singleton.class) {//②
                    if (sInstance == null) {
                        sInstance = new Singleton();//③  
                    }
                }
            }
            return sInstance;
        }
        private Singleton() {}
    }
    

      双检锁的设置可以避免在1和2位置处,在并发时假如A线程和B线程都进入了1位置,但是A获取到了锁,new了对象之后,B获取到锁之后又重复new一个实例,但是仍然在3位置处可能会有以下问题,即指令重排的问题

       new一个实例时,会分配实例内存大小,初始化对象,设置引用指向的过程,但是如果指令重排之后就有可能像上图那样子,线程A分配实例内存大小,设置了引用指向内存空间,但是B线程由于判断到引用不为空,就会在A线程初始化对象之前访问到一个空的对象。而不是再new一个对象。所以需要在实例属性前面加上volatile关键字,保证线程可见性,通过设置内存屏障方式禁止指令重排。

    public class Singleton {
    private static volatile Singleton sInstance;
    public static Singleton getInstance() {
            if (sInstance == null) {
                    synchronized (Singleton.class) {
                            if (sInstance == null) {
                               sInstance = new Singleton();
                                }
                            }
                        }
                        return sInstance;
                }
    private Singleton() {}
    }
    

      

  • 相关阅读:
    sql server 常用脚本之table操作
    sql server 常用脚本之数据库操作
    PHP 生成日历
    转 mysql 问题一则
    转 php 前端知识点
    转 nbu 知识点
    转 php python 知识点
    oralce 问题几则 ORA-19504 报错
    AWR 报告脚本实现
    转 php 框架 Php 依赖框架 后台 调用python 脚本
  • 原文地址:https://www.cnblogs.com/dashenaichicha/p/12716480.html
Copyright © 2011-2022 走看看