单例模式的双锁机制

单例模式作为常用的设计模式之一,创建单一对象并在程序活动中提供唯一实例。一般而言,单例模式的要求有

  • 单例类只能有一个实例
  • 单例类必须自己创建唯一的实例
  • 单例类必须提供获取唯一实例的方法
项目说明
目的提高内存使用效率,在程序中提供全局唯一实例
需求控制实例数目,节省系统资源的时候
思路一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
关键构造函数的私有化
应用实例设备管理器如打印机等;多进程操作同一文件
优点减少内存开销,符合
缺点违背单一职能原则,无法继承
使用场景web中的计数器,多线程处理单一文件

单例模式在单线程时不会出现问题,但在多线程时会由于计算机多线程处理方式的问题产生错误。由此JAVA推荐双锁机制,在获取实例方法中加入锁,并且确保该实例的修改会立刻反应在主存中。
在参考和修改现有实现模式的基础上,构建如下实现。
双锁(Double-Check)机制

package singleton_pattern;

public class SingleObject {
    private volatile static SingleObject instance;
    private final static Object lock=new Object();
    //当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。<可见性>
    //内部静态声明一个变量锁
    private SingleObject() {
    }
    //把构造函数写成私有就不能外部调用了
    public static SingleObject getInstance() {
        if (instance==null)
        {
            synchronized (lock) {
                //synchronized和lock能够保证任一时刻只有一个线程执行该代码块<原子性>
                //将getInstance方法标记为synchronized是对类实例进行同步
                //synchronized(类定义)是对类同步
                //synchronized(object)减小同步的粒度
                //在这里加同步锁要比将getInstance方法标记为synchronized效率要高
                if (instance==null) {
                    instance=new SingleObject();
                }
            }
        }
        return instance;
    }
    //通过该方法获取单一的实例
    public void ShowMessage() {
        System.out.println("Hello world!");
    }
}

其中涉及到几个关键词,volatile和synchronized,关于为什么要这样写,可以参照:

在wiki上推荐的是“饿汉式”的实现方式,即在程序开始前就初始化该类的实例。

public class Something {
    private Something() {}

    private static class LazyHolder {
        private static final Something INSTANCE = new Something();
    }

    public static Something getInstance() {
        return LazyHolder.INSTANCE;
    }
}

优点是实现方式简单,而且并发时不会导致错误,缺点是生成了无用对象,不满足 lazy loading。
本文是学习之余的记录,只做分享交流使用。恳请批评指正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值