单例(Singleton)模式

2019-06-20  本文已影响0人  莫库施勒

饿汉模式:

public class SingleTon{
   private static SingleTon INSTANCE = new SingleTon();
   private SingleTon(){}
   public static SingleTon getInstance(){ return INSTANCE; }
}

懒汉模式

public class SingleTon{
   private static SingleTon  INSTANCE = null;
   private SingleTon(){}
   public static SingleTon getInstance() {  
   if(INSTANCE == null){
      INSTANCE = new SingleTon(); 
    } 
    return INSTANCE;
  }
}

双重锁懒汉模式(Double Check Lock)

public class SingleTon{
  private static SingleTon  INSTANCE = null;
  private SingleTon(){}
  public static SingleTon getInstance(){if(INSTANCE == null){
   synchronized(SingleTon.class){
     if(INSTANCE == null){ 
        INSTANCE = new SingleTon();
       } 
     } 
   return INSTANCE; 
   } 
 }
}

静态内部类模式

public class SingleTon{
  private SingleTon(){}

  private static class SingleTonHoler{
     private static SingleTon INSTANCE = new SingleTon();
 }

  public static SingleTon getInstance(){
    return SingleTonHoler.INSTANCE;
  }
}

当getInstance()方法被调用时,SingleTonHoler才在SingleTon的运行时常量池里,把符号引用替换为直接引用,这时静态对象INSTANCE也真正被创建.
虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行<clinit>()方法完毕。如果在一个类的<clinit>()方法中有耗时很长的操作,就可能造成多个进程阻塞.需要注意的是,其他线程虽然会被阻塞,但如果执行<clinit>()方法后,其他线程唤醒之后不会再次进入<clinit>()方法。同一个加载器下,一个类型只会初始化一次

静态内部类也有着一个致命的缺点,就是传参的问题,由于是静态内部类的形式去创建单例的,故外部无法传递参数进去,例如Context这种参数,所以,我们创建单例时,可以在静态内部类与DCL模式里自己斟酌。

枚举单例

public enum Singleton{
  INSTANCE;
  public void method(){
        //TODO
  }
}
上一篇 下一篇

猜你喜欢

热点阅读