设计模式

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

类图

饿汉式单例

代码实现

package com.huey.pattern.singleton;

public class HungrySingleton {
    
    /**
     * 在加载类之前初始化实例
     */
    private static HungrySingleton singleton = new HungrySingleton();
    
    private HungrySingleton() {}
    
    public static HungrySingleton getInstance() {
        return singleton;
    }
}

懒汉式单例

实现代码

package com.huey.pattern.singleton;

public class LazySingleton {

    private static LazySingleton singleton = null;
    
    /**
     * 私有的构造方法,无法通过 new 操作符创建实例
     */
    private LazySingleton() {}
    
    /**
     * 获取单例,线程安全的 
     * @return
     */
    public synchronized static LazySingleton getInstance() {
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

饿汉式与懒汉式的比较

懒汉式

优点:不会产生内存浪费,因为共享实例对象开始没有被初始化,而是在获得对象的方法中动态生成实例的。

缺点:在获取共享对象的方法上,使用 syschronized 线程同步,执行效率有所降低。

恶汉式

优点:由于没有 syschronized 线程同步,执行效率高。

缺点:会产生内存浪费,因为在加载 HungrySingleton 类时就已经初始化共享对象实例。

枚举型单例

懒汉式和饿汉式都利用私有构造器实现 Singleton 类,当要使得类可序列化时,仅仅在声明中加上 "implements Serializable" 是不够的。为了维护并保证 Singleton,必须声明所有实例域都是瞬时的(transient),并提供一个 readResolve 方法。否则,每次反序列化时,都会创建一个新的实例。

private Object readResolve() {
    return INSTANCE;
}

从 Java 1.5 发行版起,实现 Singleton 还有第三种方法。只需编写一个包含单个元素的枚举类型:

package com.huey.pattern.singleton;

public enum EnumSingleton {
    
    INSTANCE("enum singleton");
    
    private String val;

    public String getVal() {
        return val;
    }
    
    private EnumSingleton(String val) {
        this.val = val;
    }
}

这种方法更加简洁,无偿地提供了序列化机制,绝对防止多次实例化。

原文地址:https://www.cnblogs.com/huey/p/4994846.html