Singleton单例模式

来源:互联网 发布:常用sql查询语句 编辑:程序博客网 时间:2024/04/28 10:52

Singleton模式是设计模式里最简单的了,但在使用时,还是要注意些细节,可能你在用时也会碰到。废话不多说,请接着看:

1 Introduction

       先看定义:

      The Singleton Pattern ensures a class has only one instance, and provides aglobal point of access to it.

      从定义可以看出,Singleton主要实现两点功能:

      1) 只有一个实例

      2)    提供全局的入口

2  Implementation

         一般是这样写的:

方法1:

public class Singleton {private static Singleton mInstance; // Static variable to hold one instance// Constructor is declared private to avoid instantiated by othersprivate Singleton() {}public static Singleton getInstance() {   if (null == mInstance){mInstance = new Singleton();}return mInstance;}}

     恩,这样写在面试时一般都能通过。但这里会有问题,特别是在多线程时。

3 Problem

     在多线程中,假设有两个线程Thread1, Thread2,都调用Singleton.getInstance(),有可能创建两个instance. 见下图(从Head First Design Pattern上抄的):

 

 

4. Improvement

         在多线程中,为了同步,一般用synchronized关键字,但具体放的位置还有关系:下面列了3种solution:

方法2:   在getInstance()前加synchronized,

public class Singleton {private static Singleton mInstance; // Static variable to hold one instance// Constructor is declared private to avoid instantiated by othersprivate Singleton() {}public static synchronized Singleton getInstance() {   if (null == mInstance){mInstance = new Singleton();}return mInstance;}}

           缺点:在每次调用getInstance()时都会阻塞在这里,这样性能会下降。实际上只要在第一次new Singleton时synchronized就可以了,其他时间没必要synchronized。

方法3: 更严谨的方法

public class Singleton { private static Singleton mInstance; // Static variable to hold one instance  // Constructor is declared private to avoid instantiated by others private Singleton() {}  public static Singleton getInstance() {     if (null == mInstance)     {     synchronized(Singleton.class)     {     if (null == mInstance)      {     mInstance = new Singleton();     }     }      }    return mInstance; }}

         这样写的好处是,只在第一次会synchronized,并且不会产生两个instance。推荐这种写法。

       当然也有不用写synchronized的方法,前提是你的程序肯定会调用该Singleton类:

方法4

public class Singleton { private static Singleton mInstance = new Singleton();  private Singleton() {}  public static Singleton getInstance() {   return mInstance; }}


5. Summary

   总结下:以前我经常用方法1,觉得也没什么不妥。但从更严谨的角度来说,还是用 方法3最好。

     欢迎讨论~~~