当前位置: 首页 > news >正文

深入单例模式

1. 饿汉模式

饿坏了,上来就先实例化一个对象,好处是代码简单,坏处是这个对象后面如果一直用不到,就是个浪费。

public class A{

    private static A a = new A();

    private A(){}

    public static A getInstance(){

        return a;

    }

}

2. 懒汉模式

懒洋洋的,用到的时候才抱佛脚。最简单的懒汉模式如下,存在线程安全问题。

public static class A{

    private static A a=null;

    private A(){}

    public static A getInstance(){

        if(a==null){

            a=new A();

        }

        return a;

    }

}

终极解决办法是使用DCL(double check lock)加volatile,如下所示:

public static class A{

    private static volatile A a=null;

    private A(){}

    public static A getInstance(){

        if(a==null){

            synchronized (A.class){

                if(a==null){

                    a=new A();

                }

            }

        }

        return a;

    }

}

  • DCL其实就是一锁二判三更新(在一锁之前加一个判断,提高并发时的效率,不需要每次一上来都先锁住消耗性能)。
  • 加volatile的目的是防止第8行发生指令重排。

第8行在底层会有3个操作:

  1. 分配一块内存
  2. 初始化这块内存(一般是调用类的构造函数)
  3. 将这块内存赋给变量(如上代码中是变量a)

如果在变量a不加volatile,上面的步骤可能发生指令重排变成1、3、2,导致a先等于一块没有初始化(2还未执行)或初始化一半(2执行了一半)的内存,这时候如果代码其他部分(不需要获取A.class的锁的部分)访问了a变量,就会读到预料外的值。

这有点类似于数据库里的“脏读”,在事务处理中的数据被该事务外读到。

 


http://www.mrgr.cn/news/2495.html

相关文章:

  • 4.Java面试题之lock 和 synchronized 区别
  • 同态加密及HElib
  • Python 选出列表中特定的元素
  • 你知道手机零部件尺寸检测的重要性吗?
  • LeetCode238.除自身以外数组的乘积
  • WPF—Triggers触发器
  • 【数据结构】二叉搜索树(二叉排序树)、平衡二叉树、红黑树、B树、B+树详解
  • Excel“取消工作表保护”忘记密码并恢复原始密码
  • EGL函数翻译--eglCreatePbufferSurface
  • ​​JVM三:JVM垃圾回收机制(GC)
  • 基于JSP的美食推荐管理系统
  • SSH协议与OpenSSH配置详解(配置密钥对验证实验)
  • LDR6020双盲插便携显示器方案:重塑连接体验的新标杆
  • 【软件测试】功能测试理论基础
  • 使用 Python和 SQLite 打造一个简单的数据库浏览器
  • 【等保测评】Ngnix模拟测评
  • Python青少年简明教程:数据类型和操作符
  • 2.Lab One —— Util
  • Spring Boot
  • 如何免费获取乡镇级边界数据geoJson数据