单例模式

简介: 所有单例模式都有一个共性,那就是这个类没有自己的状态。也就是说无论这个类有多少个实例,都是一样的;然后除此者外更重要的是,这个类如果有两个或两个以上的实例的话程序会产生错误。基于上述原因,非线程安全的实现方式,在此不再讨论。

所有单例模式都有一个共性,那就是这个类没有自己的状态。也就是说无论这个类有多少个实例,都是一样的;然后除此者外更重要的是,这个类如果有两个或两个以上的实例的话程序会产生错误。

基于上述原因,非线程安全的实现方式,在此不再讨论。下面讨论的都是线程安全的一些实现方式和存在的问题。

双重加锁模式

public class Singleton{
  private volatile static Singleton singleton;
  private Singleton(){

  }

  public static Singleton getInstance(){
    if(null == singleton){
      synchronized(Singleton.class){
        if(null == singleton){
          singleton = new Singleton();
        }
      }
    }
    return singleton;
  }
}

双重加锁模式相对于普通的单例和加锁模式而言,从性能和线程安全上来说都有很大的提升和保障。然而双重加锁模式也存在一些隐蔽不易被发现的问题。首先我们要明白在JVM创建新的对象时,主要要经过三个步骤。

    • 分配内存
    • 初始化构造器
    • 将对象指向分配的内存地址

这样的顺序在双重加锁模式下是么有问题的,对象在初始化完成之后再把内存地址指向对象。但是现代的JVM会针对字节码进行调优,这样的话就有可能导致2和3的顺序是相反的,一旦出现这样的情况问题就来了。

所以更加理想的方案是利用静态内部类的方式来创建,因为静态属性由JVM确保第一次初始化时创建,因此也不用担心并发的问题出现。当初始化进行到一半的时候,别的线程是无法使用的,因为JVM会帮我们强行同步这个过程。另外由于静态变量只初始化一次,所以singleton仍然是单例的。

静态内部类的方式

public class Singleton{

  private Singleton(){}

  public static Singleton getInstance(){
    return InnerClassSingleton.singleton;
  }

  private class InnerClassSingleton{
    protected static Singleton singleton = new Singleton();
  }
}

然而,虽然静态内部类模式可以很好地避免并发创建出多个实例的问题,但这种方式仍然有其存在的隐患。

    • 一旦一个实例被持久化后重新生成的实例仍然有可能是不唯一的。
    • 由于java提供了反射机制,通过反射机制仍然有可能生成多个实例。

单例最优方案,枚举的方式

枚举实现单例的优势

  • 自由序列化;
  • 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);
  • 线程安全;
public enum Singleton {
    INSTANCE;

    private Singleton(){}
}

参考文档:

相关文章
|
1月前
|
设计模式 安全 测试技术
【C++】—— 单例模式详解
【C++】—— 单例模式详解
|
1月前
|
设计模式 安全 Java
软件设计模式:单例模式
软件设计模式:单例模式
|
4月前
|
SQL
单例模式
单例模式
27 0
|
3月前
|
C++
【C++ 单例模式】
【C++ 单例模式】
|
4月前
|
设计模式 安全
【单例模式】—— 每天一点小知识
【单例模式】—— 每天一点小知识
|
8月前
|
设计模式 Java Spring
什么场景要使用单例模式,什么场景不能使用?
经常有小伙伴问我,设计模式学了这么久,每次看到概念也都能理解。但是,就是不知道怎么用,在哪里能用?我告诉大家,设计模式,不是为了要用而用的,而是作为前人总结下来的经验,等到哪天需要用的时候,你能想起来为你所用。
65 0
|
10月前
|
设计模式 前端开发
关于单例模式我所知道的
关于单例模式我所知道的
44 0
关于单例模式我所知道的
|
设计模式 安全 前端开发
关于单例模式,你应该了解这些
关于单例模式,你应该了解这些
关于单例模式,你应该了解这些
|
SQL 安全 Java
单例模式的理解
谈谈你对单例模式的理解。也算是老生常谈的问题了~~~
890 1
|
XML 设计模式 安全
单例模式,真不简单
单例模式,真不简单
单例模式,真不简单