其他分享
首页 > 其他分享> > 4.单例模式的五种实现

4.单例模式的五种实现

作者:互联网

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种方式,不管如何优化,在反射面前都是不安全的。

枚举是安全的,枚举的源码中,进行反射会直接抛异常。

 

标签:getInstance,Hungry,模式,LazyMan,五种,static,单例,lazyMan,public
来源: https://www.cnblogs.com/johnzhao/p/14672024.html