几种单例模式

单例模式1:

    此种模式在多线程模式下会有问题

public class Singleton{
  //私有静态实例,防止被引用,此处设置为null,是为了延迟加载
  private static Sigleton instance = null;
  
  //私有构造方法,防止被实例化
  private Singleton(){

  }
  
  //静态方法,创建实例
  public static Singleton getInstance(){
    if(instance == null){
      instance = new Singleton();
    }
  }
  
  //若该类被用于序列化,可以保证序列号前后保持一致
  public Object readResolve(){
    return instace;
  }
}

 ==================================华丽丽的分割线====================================

单例模式2

    能解决多线程的问题;

    但又会出现其它问题:由于java中创建对象和赋值是分开执行的,所以对于instance=new Singleton()其实是分开两步的,java不保证其中的执行顺序,可能会出现JVM为新的Singleton实例分配空间,然后直接赋值给成员instance,然后再去初始化instance实例,这样就有可能出错了

    例子:A,B两个线程同时进入第一个if判断

    A首先进入synchronized代码块,由于instance此时为null,则执行instance = new Singleton()

    JVM会先分配给Singleton一些空白内存,并赋值给instance,不过此时JVM并没有开始初始化Singleton,然后A离开方法;

    B进入synchronized代码块,由于instance不为null,所以马上离开并把结果返回给调用者;

    至此,B线程要Singleton实例,却发现未被实例化,从而出错

public class Singleton{
  //私有静态实例,防止被引用,此处设置为null,是为了延迟加载
  private static Sigleton instance = null;
  
  //私有构造方法,防止被实例化
  private Singleton(){

  }
  
  //静态方法,创建实例
  public static Singleton getInstance(){
    if(instance == null){
      synchronized(instance){
        if(instance == null){
          instance = new Singleton();
        }
      }
    }
  }
  
  //若该类被用于序列化,可以保证序列号前后保持一致
  public Object readResolve(){
    return instace;
  }
}

 ==================================华丽丽的分割线====================================

单例模式3

    保证多线程环境,保证互斥.

    JVM能保证一个类被加载的时候,加载过程是互斥的,这样当第一次调用getInstance的时候

    JVM能够帮助我们保证instance只被创建一次,并且保证赋值给instace的结果已初始化完毕;

    同时该方法也只会在第一次调用的时候使用互斥机制,这样也解决低性能的问题;

public class Singleton{
  //私有构造方法,防止被实例化
  private Singleton(){

  }

  //使用一个内部类来维护单例
  private static class SingleFactory(){
    private static Sigleton instance = null;
  }
  
  //静态方法,创建实例
  public static Singleton getInstance(){
    return SingleFactory.instace;
  }
  
  //若该类被用于序列化,可以保证序列号前后保持一致
  public Object readResolve(){
    return instace;
  }
}

猜你喜欢

转载自maozhetao.iteye.com/blog/2319348
今日推荐