单例模式的几种写法

一、饿汉式--无法给单例对象的构造方法传递参数,且线程不安全

/**
 * Created by serenitynanian on 2018/3/13.
 * 饿汉式--无法向单例对象的构造方法传递参数  线程不安全
 */

public class HungrySingleton {
    private static final HungrySingleton instance = new HungrySingleton();
    private HungrySingleton(){}

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

二、懒汉式--可以给构造函数传递参数,但线程不安全

/**
 * Created by serenitynanian on 2018/3/13.
 * 懒汉式-- 可以给构造函数传递参数  线程不安全
 */

public class LazySingleton {

    private static LazySingleton lazySingleton ;

    private LazySingleton(){}

    public static LazySingleton getInstance(){
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton ;
    }
}

三、双重检查--可以给构造函数传递参数,且线层安全

/**
 * Created by serenitynanian on 2018/3/13.
 * 双重检查--- 线程安全需要时可以使用此方法创建单例  线程安全
 * volatile关键字的两层含义
 * 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
 * 1.保证了不同线程对这个变量进行操作的可见性,既一个线程修改了某个变量,这个变量的新值对其他线程是立即可见的;
 * 2.禁止进行指令重排序;生成的机器指令与字节码指令顺序不一致;
 */

public class DoubleCheckSingleton {
    //volatile
    //线程并发时,当变量被改动了,所有的线程都能及时的访问到最新的数据
    //会屏蔽掉虚拟机的一些优化代码
    private volatile static DoubleCheckSingleton doubleCheckSingleton ;
    private DoubleCheckSingleton(){}

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

}

四、静态被内部类--不能给构造函数传递参数,但线程安全

/**
 * Created by serenitynanian on 2018/3/13.
 * 静态内部类创建单例---无法给构造函数传递参数,线程安全
 */

public class StaticInnerClassSingleton {

    private StaticInnerClassSingleton(){}

    private static class SingletonHolder{
        //注意:静态内部类的静态属性实例化时,是由JVM保证线程的安全---虚拟机的机制
        private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
    }

    //只有调用了getInstance方法之后,才会实例化StaticInnerClassSingleton
    public static StaticInnerClassSingleton getInstance(){
        return SingletonHolder.instance ;
    }
}

五、使用枚举创建单例

/**
 * Created by serenitynanian on 2018/3/13.
 * 枚举的方式创建单例
 * java设计者建议使用的最优方法,参数和安全都可以自己控制;--《Effective Java》 java高效编程
 */

public enum  EnumSingleton {

    instance(1,"参数");

    private int index ;
    private String params ;

    //参数可控的
    EnumSingleton(int index, String params) {
        this.index = index ;
        this.params = params ;
    }
    public void operate(){
        System.out.println("------operate------");
    }
}

你可能感兴趣的:(单例模式的几种写法)