标签:nbsp single zed volatile ati 模式 i++ ring string
1.饿汉式,这种方式不推荐,会造成资源的浪费。
public class Hungry { private Hungry(){ } private static Hungry hungry = new Hungry(); public static Hungry getInstance(){ return hungry; } public static void main(String[] args) { Hungry hungry1 = Hungry.getInstance(); Hungry hungry2 = Hungry.getInstance(); System.out.println(hungry1); System.out.println(hungry2); } }
2.单线程中的懒汉式
public class LazyMan { private LazyMan(){ } private static LazyMan lazyMan = null; public static LazyMan getInstance(){ if(lazyMan == null){ lazyMan = new LazyMan(); } return lazyMan; } public static void main(String[] args) { LazyMan lazyMan1 = LazyMan.getInstance(); LazyMan lazyMan2 = LazyMan.getInstance(); System.out.println(lazyMan1); System.out.println(lazyMan2); } }
3.双重锁机制的懒汉式,最推荐的一种
public class ThreadLazyMan { private ThreadLazyMan(){ System.out.println(Thread.currentThread().getName()); } private static volatile ThreadLazyMan lazyMan = null; public static ThreadLazyMan getInstance(){ if(lazyMan == null){ synchronized (ThreadLazyMan.class){ if(lazyMan == null){ lazyMan = new ThreadLazyMan(); } } } return lazyMan; } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(()->{ ThreadLazyMan.getInstance(); }).start(); } } }
4.静态内部类的饿汉式
public class LazyInnerClass { private LazyInnerClass(){ System.out.println(Thread.currentThread().getName()); } static class Inner{ public static LazyInnerClass lazyInnerClass = new LazyInnerClass(); } public static LazyInnerClass getInstance(){ return Inner.lazyInnerClass; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(()->{ LazyInnerClass.getInstance(); }).start(); } } }
5.枚举,最为安全的模式,反射也无法破解
public enum SingleEnum { INSTANCE; public static SingleEnum getInstance(){ return INSTANCE; } }
总结:
前面4种方式,不管如何优化,在反射面前都是不安全的。
枚举是安全的,枚举的源码中,进行反射会直接抛异常。
标签:nbsp single zed volatile ati 模式 i++ ring string
原文地址:https://www.cnblogs.com/johnzhao/p/14672024.html