单例模式的8种情况

1.饿汉式单例
特点:在使用实例之前就将实例创建出来,JVM保证线程安全。

public class Singleton01 {
    private static final Singleton01 INSTANCE = new Singleton01();

    private Singleton01(){};// 将构造方法私有化,其他类就不能new出这个实例,只能通过getInstance获取。

    public static Singleton01 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton01 s1 = Singleton01.getInstance();
        Singleton01 s2 = Singleton01.getInstance();
        System.out.println("s1==s2:"+(s1==s2));
        // 结果为true,说明不管调用多少次getInstance(),都是同一个实例
    }
}

2.静态块饿汉式单例
特点:在使用实例之前在静态块中将实例创建出来,JVM保证线程安全。

public class Singleton02 {
    private static final Singleton02 INSTANCE;
	
	private Singleton02(){};
	
    static {
        INSTANCE = new Singleton02();// 使用静态块创建实例
    }

    public static Singleton02 getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        Singleton02 s1 = Singleton02.getInstance();
        Singleton02 s2 = Singleton02.getInstance();
        System.out.println("s1==s2:"+(s1==s2));
        // 结果为true,说明不管调用多少次getInstance(),都是同一个实例
    }
}

3.懒汉式单例
特点:线程不安全

public class Singleton03 {
    private static Singleton03 INSTANCE;

    private Singleton03(){};

    public static Singleton03 getINSTANCE(){
        if(INSTANCE==null){
            try{
                Thread.sleep(1);
            }catch (Exception e){
                e.printStackTrace();
            }
            INSTANCE = new Singleton03();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                   System.out.println(Singleton03.getINSTANCE().hashCode());
                }
            }).start();
        }
    }
}

4.加锁懒汉式单例
特点:线程安全,但效率降低

public class Singleton04 {
    private static Singleton04 INSTANCE;

    private Singleton04(){};

    public static synchronized Singleton04 getINSTANCE(){
    // 方法用同步锁修饰。一个线程访问一个对象的同步代码块时,其他试图访问该对象的线程被阻塞。
        if(INSTANCE==null){
            try{
                Thread.sleep(1);
            }catch (Exception e){
                e.printStackTrace();
            }
            INSTANCE = new Singleton04();
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                System.out.println(Singleton04.getINSTANCE().hashCode());
            }).start();
        }
    }
}

5.加锁检查懒汉式单例
特点:线程安全,效率提高,但多线程访问情况下不能做到只有一个实例

public class Singleton05 {
    private static Singleton05 INSTANCE;

    private Singleton05(){};

    public static Singleton05 getINSTANCE(){
        if(INSTANCE==null){
            synchronized (Singleton05.class){
                // 代码块用同步锁修饰。
                try{
                    Thread.sleep(1);
                }catch (Exception e){
                    e.printStackTrace();
                }
                INSTANCE = new Singleton05();
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                System.out.println(Singleton05.getINSTANCE().hashCode());
            }).start();
        }
    }
}

6.双重检查懒汉式单例
特点:线程安全,效率提高,且多线程访问情况下能做到只有一个实例

public class Singleton06 {
    private static volatile Singleton06 INSTANCE;
    // 必须加上volatile防止指令重排
    private Singleton06(){};

    public static Singleton06 getINSTANCE(){
        if(INSTANCE==null){
            synchronized (Singleton06.class){
                // 代码块用同步锁修饰。
                if(INSTANCE==null){
                    try{
                        Thread.sleep(1);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    INSTANCE = new Singleton06();
                }
            }
        }
        return INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                System.out.println(Singleton06.getINSTANCE().hashCode());
            }).start();
        }
    }
}

7.静态内部类懒汉式单例
特点:JVM保证线程安全,效率提高。且多线程访问情况下能做到只有一个实例

public class Singleton07 {

    private Singleton07(){};

    private static class Singleton07Holder{// 静态内部类创建外部类实例
        private static final Singleton07 INSTANCE = new Singleton07();
    }

    public static Singleton07 getInstance(){
        // 返回该实例
        return Singleton07Holder.INSTANCE;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                System.out.println(Singleton07.getInstance().hashCode());
            }).start();
        }
    }
}

8.枚举单例懒汉式单例
特点:不仅可以解决线程同步,还可以防止反序列化

public enum Singleton08 {

    INSTANCE;

    public static void main(String[] args) {
        for (int i=0;i<10;i++){
            new Thread(()->{
                System.out.println(Singleton08.INSTANCE.hashCode());
            }).start();
        }
    }
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页