单件模式(Singleton Pattern)

为什么引入单件模式

有些对象只需要一个,例如线程池、缓存、对话框、处理偏好设置和注册表的对象、日志对象、打印机和显卡等设备的驱动对象,这些对象只能有一个实例,如果有多个就会出现问题。如果用全局变量,那么必须在程序一开始就创建好对象,非常耗费资源,可以用单件模式,在需要时创建对象。单价模式的关键是保证一个对象只被实例化一次。

单件模式分析

下面是一个经典的单件模式类的实现:

public class Singleton {
    private static Singleton uniqueInstance;

    private Singleton(){}

    public static Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton();
        }

        return uniqueInstance;
    }
}

构造方法为私有,使外部类无法调用构造器,利用一个静态方法实例化对象,若对象已存在,就返回该对象。

单件模式的定义

单件模式确保一个类只有一个实例,并提供一个全局访问点。

多线程操作产生的问题

当单件类没有实例化时,有两个线程同时创建单件类的对象,这时候,判断均为null,两个线程都会实例化一个单件对象。

解决方法

  • 加锁或synchronized,在这种情况下,因为只有第一次实例化才需要加锁,其余时间调用这个方法都要加锁,产生了不必要的开销,若getInstance方法对性能要求不大,可以采用这种方法;
  • “急切”创建实例,而不用延迟化的做法,即在单件类中,直接让uniqueInstance = new Singleton()。
  • 使用双重检查加锁,即首先检查实例是否已经创建了,若尚未创建,才加锁,这样,只有第一次创建对象才加锁。代码示例如下:
public class Singleton1 {
    private volatile static Singleton1 uniqueInstance;

    private Singleton1(){}

    public static Singleton1 getInstance(){
        if(uniqueInstance == null){
            synchronized (Singleton1.class){
                if(uniqueInstance == null){
                    uniqueInstance = new Singleton1();
                }
            }
        }
        return uniqueInstance;
    }
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页