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种方式,不管如何优化,在反射面前都是不安全的。
枚举是安全的,枚举的源码中,进行反射会直接抛异常。
原文:https://www.cnblogs.com/johnzhao/p/14672024.html