线程安全的单例模式

一、饿汉式

java 复制代码
package com.day3;
//饿汉式(线程安全)
public class Singleton1 {

    //类加载时,创建当前实例(类加载的过程是线程安全的)
    private static final Singleton1 INSTANCE=new Singleton1();

    //私有化构造函数 防止外部调用对象
    private Singleton1(){}

    public static Singleton1 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton1 s1= Singleton1.getInstance();
        Singleton1 s2= Singleton1.getInstance();
        Singleton1 s3= Singleton1.getInstance();

        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());

    }
}

二、懒汉式

java 复制代码
package com.day3;



//懒汉式(synchronized同步方法 效率不高且性能差)
public class Singleton2 {
    //实例化对象(未创建)
    private static Singleton2 instance;

    private Singleton2(){}


    public static Singleton2 getInstance(){
        //懒加载(延迟加载):使用的时候 在创建实例对象
        if(instance==null){
            instance=new Singleton2();
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton2 s1=Singleton2.getInstance();
        Singleton2 s2=Singleton2.getInstance();
        Singleton2 s3=Singleton2.getInstance();
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
    }
}

三、双重校验

java 复制代码
package com.day3;

//双重校验
public class Singleton3 {
    //定义单例对象
    private static volatile Singleton3 instance;

    //私有构造方法
    private Singleton3(){}

    public static Singleton3 getInstance(){
        if(instance==null){
            synchronized (Singleton3.class){
                if(instance==null){
                    instance=new Singleton3();
                }
            }
        }
        return instance;
    }
  public static void main(String[] args) {
        Singleton2 s1=Singleton2.getInstance();
        Singleton2 s2=Singleton2.getInstance();
        Singleton2 s3=Singleton2.getInstance();
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
    }
}

四、静态内部类(面试题)

java 复制代码
package com.day3;
//静态内部类【推荐】(线程安全,且懒加载)
public class Singleton4 {
    //私有化构造函数
    private Singleton4(){};

    //静态内部类:第一次使用该类时 才会触发类加载(线程安全)
    private static class SingletonHolder{

        //静态内部类被加载时 懒加载的方式 创建单例对象
        private static final Singleton4 INSTANCE =new Singleton4();
    }

    public static Singleton4 getInstance(){
        //第一次调用方法时 静态内部类被加载
        return SingletonHolder.INSTANCE;
    }

    public static void main(String[] args) {
        Singleton4 s1=Singleton4.getInstance();
        Singleton4 s2=Singleton4.getInstance();
        Singleton4 s3=Singleton4.getInstance();

        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s3.hashCode());
    }
}