七种单例模式的那些事

一、饿汉式(静态变量)

public class Singleton1 {
    public static void main(String[] args) {

        Singleton1 t1 = Singleton1.getInstance();
        Singleton1 t2 = Singleton1.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //饿汉式(静态变量)
    //私有化构造方法
    private Singleton1() {
    }

    //创建内部静态实例
    private final static Singleton1 instance = new Singleton1();

    //提供公有的get实例方法
    public static Singleton1 getInstance() {
        return instance;
    }
    /*
    * 总结:类加载的时候完成实例化,避免了线程同步问题,
    * 但如果该类未被使用,却完成实例化会造成内存浪费
    *
    * */

}

二、饿汉式(静态代码块)

public class Singleton2 {
    public static void main(String[] args) {

        Singleton2 t1 = Singleton2.getInstance();
        Singleton2 t2 = Singleton2.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //饿汉式(静态代码块)
    //私有化构造方法
    private Singleton2() {
    }

    //创建内部静态实例
    private  static Singleton2 instance ;
    //静态代码块
    static {
         instance = new Singleton2();
    }

    //提供公有的get实例方法
    public static Singleton2 getInstance() {
        return instance;
    }
    /*
    * 总结(同静态变量):类加载的时候完成实例化,避免了线程同步问题,
    * 但如果该类未被使用,却完成实例化会造成内存浪费
    *
    * */

}

三、懒汉式(静态代码块)

public class Singleton3 {
    public static void main(String[] args) {

        Singleton3 t1 = Singleton3.getInstance();
        Singleton3 t2 = Singleton3.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //懒汉式(静态代码块)
    //私有化构造方法
    private Singleton3() {
    }

    //创建内部静态实例
    private  static Singleton3 instance ;


    //提供公有的get实例方法
    public static Singleton3 getInstance() {
        if(instance==null){
            instance = new Singleton3();
        }
        return instance;
    }
    /*
    * 总结:起到了懒加载的作用,但只适用于单线程的情况
    * 如果多线程情况下,有一个线程if(instance==null)还没来得及创建对象,另外一个线程也进入了方法,就会出现多个实例
    *
    * */

}

四、懒汉式(静态代码块,线程安全)

public class Singleton4 {
    public static void main(String[] args) {

        Singleton4 t1 = Singleton4.getInstance();
        Singleton4 t2 = Singleton4.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //懒汉式(静态代码块,线程安全)
    //私有化构造方法
    private Singleton4() {
    }

    //创建内部静态实例
    private  static Singleton4 instance ;


    //提供公有的get实例方法
    public static synchronized Singleton4 getInstance() {
        if(instance==null){
            instance = new Singleton4();
        }
        return instance;
    }
    //同步代码块,是一种错误的写法

   /* public static synchronized Singleton4 getInstance() {
        if(instance==null){
            synchronized (Singleton4.class){
                instance = new Singleton4();
            }
        }
        return instance;
    }*/
    /*
    * 总结:线程安全,但效率较低。
    *
    * */

}

五、DoubleCheck实现单例(volatile禁止重排序)

public class Singleton5 {
    public static void main(String[] args) {

        Singleton5 t1 = Singleton5.getInstance();
        Singleton5 t2 = Singleton5.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //DoubleCheck(volatile禁止重排序)
    //私有化构造方法
    private Singleton5() {
    }

    //创建内部静态实例
    private  static volatile Singleton5 instance ;


    //提供公有的get实例方法
    

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

            }
        }
        return instance;
    }
    /*
    * 总结:线程安全,但效率较低。
    *
    * */

}

六、静态内部类实现单例

public class Singleton6 {
    public static void main(String[] args) {

        Singleton6 t1 = Singleton6.getInstance();
        Singleton6 t2 = Singleton6.getInstance();
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //静态内部类
    //私有化构造方法
    private Singleton6() {
    }




    //提供公有的get实例方法
    private static class StaticSingleton{
        //创建静态内部内部静态实例
        private  static  Singleton6 instance=new Singleton6() ;
    }

    public static Singleton6 getInstance() {
        return StaticSingleton.instance;
    }
    /*
    * 总结:当调用getInstance的时候才用加载静态内部类,实现了懒加载
    * 静内部类的静态属性加载类的时候才会被jvm加载,保证了线程安全性
    *
    * */

}

七、枚举实现单例

public class Singleton7 {
    public static void main(String[] args) {

        Singleton t1 = Singleton.INSTANCE;
        Singleton t2 = Singleton.INSTANCE;
        System.out.println(t1 == t2);
        System.out.println(t1.hashCode());
        System.out.println(t2.hashCode());
    }

    //枚举实现单例
    enum Singleton {
        INSTANCE
    }


    /*
     * 总结:jdk1.5以后的特性,线程安全,可以防止反序列化
     * 推荐使用
     *
     * */

    /*
    * 总共介绍了七种单例模式,其中推荐使用的有:
    *饿汉式(静态代码块)实现单例(单线程推荐)
    * 静态内部类实现单例
    * 枚举实现单例(官方推荐)
    * */

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值