创建型-单例模式

2020/05/13

一个类只有一个对象实例,并且提供全局的访问

常见的几种方法

/**
 * 饿汉式  线程安全  在类装载就完成实例化,没达到懒加载(使用较多)
 */
class Singleton1 {

    private static Singleton1 instance = new Singleton1();

    private Singleton1() {
    }

    public static Singleton1 getInstance() {
        return instance;
    }
}

// 懒汉式 解决了懒加载  只有加锁才是线程安全,效率太低  不讨论


/**
 * 双重检测 (双重检查锁) 解决线程安全 懒加载  效率
 */
class Singleton2 {

    //volatile 保证修改,其他线程可见       防止指令重排(轻量级synchronized)
    private static volatile Singleton2 instance;

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        if (instance == null) {
            synchronized (Singleton2.class) {
                if (instance == null) {
                    instance = new Singleton2();
                }
            }

        }
        return instance;
    }
}
/**
 * 静态内部类 Singleton3在装载不会立即实例化 而是在需要实例化时 调用getInstance
 * 才会装载SingletonHolder 从而完成实例化   (推荐使用)
 */
class Singleton3 {
    private static class SingletonHolder {
        private static final Singleton3 INSTANCE = new Singleton3();
    }
    private Singleton3 (){}
    public static Singleton3 getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

/**
 * 枚举 这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
 */

enum Singleton5 {
    INSTANCE;
    public void whateverMethod() {
    }
}

实例:

  1. Hibernate的sessionFactory
  2. 创建HttpClient(饿汉式)
@Slf4j
public class HttpClientUtil {


   private static CloseableHttpClient httpClient = HttpClients.createDefault();


    private HttpClientUtil() {
    }

    /**
     * 创建httpclient
     */
    public static CloseableHttpClient getInstance() {
        return httpClient;
    }


    /**
     * 释放httpclient
     */
    public static void release() throws IOException {
        if (httpClient != null) {
            httpClient.close();
            log.info("释放HttpClient");
        }
    }
}
  1. JDK源码 Runtime(饿汉模式)

    image-20200411010656909

结论:

不建议使用懒汉方式 建议使用饿汉方式

只有在懒加载 推荐使用静态内部类 也可使用双重锁校验

如果涉及到反序列化创建对象时 可以使用枚举方式

使用场景

  1. 频繁创建销毁的对象

  2. 创建对象消耗过多资源,但又经常访问的对象
  3. 工具类对象

Post Directory