欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 单例模式实现的几种方式

程序员文章站 2022-03-07 22:41:07
...

饱汉模式

import java.util.Objects;

/**
 * 线程安全的单例模式(饱汉)
 *
 * @author Chris
 * @date 2020/02/28 23:37
 * @since 1.0.0
 */
public class Singleton1 {
    private static volatile Singleton1 ourInstance;

    /** DCL 双重检查锁机制 */
    public static Singleton1 getInstance() {
        if (Objects.isNull(ourInstance)) {
            synchronized (Singleton1.class) {
                if (Objects.isNull(ourInstance)) {
                    ourInstance = new Singleton1();
                }
            }
        }
        return ourInstance;
    }

    private Singleton1() {
    }
}

饿汉(懒汉)模式

/**
 * 线程安全的单例模式(饿汉)
 *
 * @author Chris
 * @date 2020/02/28 23:45
 * @since 1.0.0
 */
public class Singleton2 {
    private static Singleton2 ourInstance = new Singleton2();

    public static Singleton2 getInstance() {
        return ourInstance;
    }

    private Singleton2() {
    }
}

饱汉与饿汉模式的区别在于,加载的时机。

静态内部类模式


/**
 * JVM层面保证了只会有一个实例对象。那么问题来了,这种方式和饿汉模式又有什么区别呢?
 * 不也是立即加载么?实则不然,加载一个类时,其内部类不会同时被加载。
 * 一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。
 *
 * @author Chris
 * @date 2020/02/28 23:54
 * @since 1.0.0
 */
public class Singleton3 {

    private Singleton3() {
    }

    private static class SingletonStaticInner {
        private static SingletonStaticInner singletonStaticInner = new SingletonStaticInner();
    }

    public static SingletonStaticInner getInstance() {
        return SingletonStaticInner.singletonStaticInner;
    }

    /** 保证序列化与反序化时也能够是单例 */
    protected Object readResolve() {
        System.out.println("调用了readResolve方法");
        return SingletonStaticInner.singletonStaticInner;
    }
}

// 序列化与反序列化
//         try {
//             SingletonStaticInner serialize = SingletonStaticInner.getInstance();
//             System.out.println(serialize.hashCode());
//             //序列化
//             FileOutputStream fo = new FileOutputStream("tem");
//             ObjectOutputStream oo = new ObjectOutputStream(fo);
//             oo.writeObject(serialize);
//             oo.close();
//             fo.close();
//             //反序列化
//             FileInputStream fi = new FileInputStream("tem");
//             ObjectInputStream oi = new ObjectInputStream(fi);
//             SingletonStaticInner serialize2 = (SingletonStaticInner) oi.readObject();
//             oi.close();
//             fi.close();
//             System.out.println(serialize2.hashCode());
//         } catch (Exception e) {
//             e.printStackTrace();
//         }

相关标签: java spring