Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

JAVA中的单例模式

$
0
0

单例模式顾名思义,就是只有一个实例。

作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象

 

单例类的类图在我的空间相册里面可以看到,即singleton.jpg

 

显然单例模式的特点有三个:

1.某个类只能有一个实例;

2.它必须自行创建这个实例;

3.它必须自行向整个系统提供这个实例。也就是公开这个类的接口。

对一些类来说,只有一个实例是很重要的。举一个简单的例子:每台计算机可以有若干个打印机,但只能有一台在某一时刻处于工件状态下,以避免两个打印作业同时输出到打印机中而造成打印错误。

 

下面举几个单例类的写法(假定单例类的类名为Singleton.java):

第一种:

 

public  static  Singleton  s;

public  static Singleton  getInstance(){

        if(null==s){

                 s=new Singleton();

        }

        return s;

}

 

上述代码不是线程安全的,原因如下:

  如果一个线程在到达粗体表示的代码之前发生切换,那么成员变量s仍然是null,然后另一个线程可能接下来进入到if块中,两个不同的单例类的实例就被创建。这样就违背的单例模式的特点。这种情况虽然很少出现,但是一旦出现,这样的错误就很难被人察觉出来。

 

第二种:

public   static  Singleton  s;

public  static  Singleton   getInstance(){

        if(null==s){

                synchronized(Singleton.class){

                             if(null==s){

                                        s=new  Singleton();

                             } 

                 }

        }

        return  s;

}

 

上面这种方法使用了线程同步的知识,从而保证了线程的安全性。解释如下:

        在这个方法里面,如果一个线程进入同步块之后又被切换,另一个线程接着进入if块。当线程一退出同步块时,线程2会重新检查s是否仍然为null。由于线程一设置的s为成员变量,所以线程二的第二次检查失败,第二个单例类实例不会被创建。

 

 


 

作者:Ada168855 发表于2013-3-12 15:46:16 原文链接
阅读:36 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>