ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码
当前位置:首页 >> 软件工程 >> 深入解析单例模式

深入解析单例模式(4/6)

来源:网络整理     时间:2016-01-15     关键词:

本篇文章主要介绍了"深入解析单例模式",主要涉及到方面的内容,对于软件工程感兴趣的同学可以参考一下:   单例模式在程序设计中非常的常见,一般来说,某些类,我们希望在程序运行期间有且只有一个实例,原因可能是该类的创建需要消耗系统过多的资源、花费很多的时间,或者业...

  我们知道使用synchronized关键字进行同步,意味着就是独占锁,同一时刻只能有一个线程执行同步块里面的代码,还要涉及到锁的争夺、释放等问题,是很消耗资源的。单例模式,构造函数只会被调用一次。如果我们不加19行,即不在进入同步块之前进行非空判断,如果之前已经有线程创建了该类的实例了,那每次的访问该实例的方法都会进入同步块,这会非常的耗费性能.如果进入同步块之前加上了非空判断,发现之前已经有线程创建了该类的实例了,那就不必进入同步块了,直接返回之前创建的实例即可。这样就基本上解决了线程同步导致的性能问题。

多线程下单例的优雅的解决方案:

上面的实现使用了synchronized同步块,并且用了双重非空校验,这保证了懒汉式单例模式在多线程环境下的有效性,但这种实现感觉还是不够好,不够优雅。

下面介绍一种优雅的多线程下单例模式的实现方案:

 1package singleton;
 2 3publicclass GracefulSingleton {
 4private GracefulSingleton(){
 5         System.out.println("创建GracefulSingleton实例一次!");
 6    }
 7
     //类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 8privatestaticclass SingletonHoder{
       //静态初始化器,由JVM来保证线程安全
9privatestatic GracefulSingleton instance = new GracefulSingleton(); 10 } 1112publicstatic GracefulSingleton getInstance(){ 13return SingletonHoder.instance; 14 } 15 }

上面的实现方案使用一个内部类来维护单例类的实例,当GracefulSingleton被加载的时候,其内部类并不会被初始化,所以可以保证当GracefulSingleton被装载到JVM的时候,不会实例化单例类,当外部调用getInstance方法的时候,才会加载内部类SingletonHoder,从而实例化instance,同时由于实例的建立是在类初始化时完成的,所以天生对多线程友好,getInstance方法也不需要进行同步。

单例模式本质上是控制单例类的实例数量只有一个,有些时候我们可能想要某个类特定数量的实例,这种情况可以看做是单例模式的一种扩展情况。比如我们希望下面的类SingletonExtend只有三个实例,我们可以利用Map来缓存这些实例。

相关图片

相关文章