单例模式定义

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。

每台计算机可以有若干个打印机,但只能有一个 Printer Spooler,以避免两个打印作业同时输出到打印中。

每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。

总之,选择单例模式就是为了避免不一致状态。

单例模式的特点

➢ 单例类只能有一个实例。

➢ 单例类必须自己创建自己的唯一实例。

➢ 单例类必须给所有其他对象提供这一实例。

单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性

单例的四大原则

➢构造私有

➢以静态方法或者枚举返回实例

➢确保实例只有一个,尤其是多线程环境

➢确保反序列话时不会重新构建对象

实现单例模式的方式

1.饿汉式(立即加载)

饿汉式单例在类加载初始化时就创建好一个静态的对象供外部使用。

除非系统重启,这个对象不会改变,所以本身就是线程安全的。

public class SingletonHugry {

    public SingletonHugry() { }

    private static SingletonHugry single = new SingletonHugry();

    public static SingletonHugry getInstance() {
        return single;
    }

    public static void main(String[] args) {
        SingletonHugry instance = SingletonHugry.getInstance();
    }
}

存在的问题

在没有使用这个对象的情况下就加载到内存是一种很大的浪费。

针对这种情况,有一种新的思想提出——延迟加载,也就是所谓的懒汉式。

2.懒汉式(延迟加载)

该示例在调用getInstance()时才会创建对象,起到了延迟加载的作用。

但在多线程环境下会产生多个 Singleton 对象,存在线程安全问题。

public class SingletonLazy {

    public SingletonLazy() {}

    private static SingletonLazy single = null;

    public static SingletonLazy getInstance() {
        if (single == null){
            single = new SingletonLazy();
        }
        return single;
    }

    public static void main(String[] args) {
        SingletonHugry instance = SingletonHugry.getInstance();
    }
}

3.同步锁(解决线程安全问题)

在方法上加 synchronized 同步锁或是用同步代码块对类加同步锁。

此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下。

下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。

public class Singleton {

    private Singleton() { }

    private static Singleton single = null;

    public static synchronized Singleton getInstance() { 
        if (single == null) { 
            single = new Singleton(); 
        }
        return single; 
    }
}

Other

此外,还有双重检查锁(提高同步锁的效率)和静态内部类等等可以实现 ...

文章作者: 已删除用户
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yida
Mark Interview
喜欢就支持一下吧