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

java单例模式的实现方式

程序员文章站 2022-06-03 15:13:45
...

单例模式的六种实现方式,代码注释比较详细,不多说,请看详细代码

一、饿汉模式/立即加载模式

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 立即加载/饿汉模式
 * 此模式是在类被加载的时候对象已经被创建,不管有没有使用,都创建了
 * 此模式是线程安全的
 */
public class Singleton1 {
    private static Singleton1 singleton = new Singleton1();

    private Singleton1(){}

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

二、懒汉模式/延迟加载模式

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 延迟加载/懒汉模式
 * 此模式是在调用getInstance()方法的时候实例才会被创建
 * 此模式是非线程安全的
 */
public class Singleton2 {
    private static Singleton2 singleton;

    //私有化构造器
    private Singleton2(){}

    public static Singleton2 getInstance(){
        if(singleton == null){
            singleton = new Singleton2();
        }
        return singleton;
    }
}

 懒汉模式的优化,使用双检查锁机制,可以满足线程安全和高性能

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 延迟加载/懒汉模式
 * 此模式是在调用getInstance()方法的时候实例才会被创建
 * 如果单独使用synchronized关键字,则会影响效率
 * 所以这里使用DCL(Double Check Locking)双检查锁机制,既保证了线程安全,又保证了效率
 *
 */
public class Singleton2a {
    /*
    这里在声明变量时使用了volatile关键字来保证其线程间的可见性;
    在同步代码块中使用二次检查,以保证其不被重复实例化。
    集合其二者,这种实现方式既保证了其高效性,也保证了其线程安全性。
     */
    private volatile static Singleton2a singleton2a;

    //私有化构造器
    private Singleton2a(){}

    public static Singleton2a getInstance(){
        if(singleton2a == null){
            synchronized (Singleton2a.class){
                if(singleton2a == null){
                    singleton2a = new Singleton2a();
                }
            }
        }
        return singleton2a;
    }
}

三、静态内置类模式

package com.shone.thread.singleton;

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 使用静态内置类实现单例模式
 * 此模式是线程安全的
 */
public class Singleton3 {
    //内部类
    private static class InnerSingleton{
        private static Singleton3 singleton = new Singleton3();
    }

    private Singleton3(){}

    public static Singleton3 getInstance(){
        return InnerSingleton.singleton;
    }
}

四、序列化与反序列化模式(其实应该叫静态内置类模式的序列化问题优化)

package com.shone.thread.singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 序列化和反序列化的单例模式
 * 静态内置类可以达到线程安全问题,但是如果遇到需要序列化和反序列化对象是,则会出现问题
 * 序列化对象的hashCode和反序列化后得到对象的hashCode的值不一样,单例被破坏了
 *
 * 在中定义一个readResolve()方法,反序列化的时候会去调用这个方法
 */
public class Singleton4 implements Serializable{
    private final static long serivalVersionUID=888L;

    private static class InnerSington{
        private static Singleton4 singleton = new Singleton4();
    }

    private Singleton4(){}

    public static Singleton4 getInstance(){
        return InnerSington.singleton;
    }

    //该方法在反序列化时会被调用,该方法不是接口定义的方法
    //反序列化的实例和序列化的实例是同一个实例
    protected  Object readResolve() throws ObjectStreamException {
        return InnerSington.singleton;
    }
}

五、静态代码块模式

package com.shone.thread.singleton;

/**
 * Created by Xiao GuoJian on 2018/1/25.
 * 使用静态代码块实现单例模式
 *
 * 静态代码块在类加载的时候执行,并且只执行一次
 */
public class Singleton5 {
    private static Singleton5 singleton;

    static {
        singleton = new Singleton5();
    }
    private Singleton5(){}

    private static Singleton5 getInstance(){
        return singleton;
    }
}

六、枚举模式

package com.shone.thread.singleton;

/**
 * Created by Xiao GuoJian on 2018/1/25.
 *
 * 使用枚举实现单例模式
 *
 * 利用的是枚举的构造方法在类加载的时候被调用的特性,跟静态代码块比较类似
 * 使用方式:SingletonEnum.singletonFactory.getInstance();
 */
public enum  SingletonEnum {
    singletonFactory;

    private Singleton6 singleton;

    //枚举的构造方法是在类加载的时候执行的
    private SingletonEnum(){
        singleton = new Singleton6();
    }

    public Singleton6 getInstance(){
        return singleton;
    }
}
//需要实现单例的类
class Singleton6{
    public Singleton6(){}
}

 枚举模式的优化

package com.shone.thread.singleton;

/**
 * Created by Xiao GuoJian on 2018/1/25.
 *
 * 完善使用枚举实现单例模式
 * 枚举实现单例默认,暴露了实现细节
 * 此代码则是将实现方式隐藏起来,直接调用即可
 */
public class SingletonFactory {
    private enum  SingletonEnum {
        singletonFactory;

        private Singleton7 singleton;

        //枚举的构造方法是在类加载的时候执行的
        private SingletonEnum(){
            singleton = new Singleton7();
        }

        public Singleton7 getInstance(){
            return singleton;
        }
    }

    public static Singleton7 getInstance(){
        return SingletonEnum.singletonFactory.getInstance();
    }

}

//需要实现单例的类
class Singleton7{
    public Singleton7(){}
}