现在的位置: 首页 > 综合 > 正文

如何使用Java Singleton模式

2014年02月09日 ⁄ 综合 ⁄ 共 2380字 ⁄ 字号 评论关闭

Quotes: http://www.builder.com.cn/2007/0808/446992.shtml

 

Java Singleton

模式属于管理实例化过程的设计模式家族。
Singleton

是一个无法实例化的对象。这种设计模式暗示,在任何时候,只能由
JVM

创建一个
Singleton

(对象)实例。
如果实例不存在,你通过创建类的新实例的方法建立一个类来执行这个模式;如果存在类的一个实例,就只会返回那个对象的一个引用。


Singleton


模式的运行机制

以下是
Singleton

模式的一个典型例子:

public class Singleton {

       
private final static Singleton INSTANCE = new Singleton();


 

   
// Private constructor suppresses generation of

   
// a (public) default constructor

   
private Singleton() {}


 

   
public static Singleton getInstance() {

     
return INSTANCE;

   
}

 
}

标准的
Singleton

模式并不使用直接静态变量实例化进行声明——它实例化构造器中的一个静态实例变量,而不查看它是否已经存在:

public class ClassicSingleton {

   
private static ClassicSingleton INSTANCE = null;

   
private ClassicSingleton() {

      
// Exists only to defeat instantiation.

   
}

   
public static ClassicSingleton getInstance() {

      
if(INSTANCE == null) {

         
INSTANCE = new ClassicSingleton();

      
}

      
return INSTANCE;

   
}

 
}

Singleton

类的默认构造器被设为私有,这样做可防止其它类使用
new

关键字直接将对象实例化。对返回
Singleton

对象的实例方法应用一个静态修饰符,这使得它成为一个类级方法,不创建对象即可进行访问。

何时需要使用
Singleton

当你只需要一个类实例时,
Singleton

才真正有用;如果类拥有几个实例,使用
Singleton

就不再适用。

设计系统时,你通常希望控制对象的用法,防止用户(包括你自己)复制对象或建立新实例。例如,你可以使用它创建一个连接池。每次程序需要往数据库中写入内容时才创建一个新连接的做法并不明智;相反,一个或一组已经在池中的连接就可以使用
Singleton

模式实例化。

Singleton

模式常常和工厂方法模式一同使用,创建一个系统级资源,使用这个资源的代码并不知道它的特殊类型。抽象窗口工具包(
AWT

)就是组合使用这两个模式的典型例子。在
GUI

应用程序中,对每个应用程序实例,你一般只需要一个图形元素的实例,如打印
(Print)

对话框或
OK

按钮。

注意潜在的问题

虽然
Singleton

设计模式是最简单的设计模式之一,但它也存在一些缺陷。

多线程应用程序中的构造问题

在多线程应用程序中,你必须仔细构造
Singleton

模式。当
Singleton

不存在时,如果两个线程即将同时执行创建方法,这两个线程必须检查
Singleton

实例,但只有一个线程应当创建新对象。这个问题的典型解决办法就是对类使用相互排斥,指出对象正在被实例化。这是
Singleton

的一个线程安全的版本:

public class Singleton

 
{

  
// Private constructor suppresses generation

  
// 
of a (public) default constructor

  
private Singleton() {}


 

  
private static class SingletonHolder

  
{

    
private final static Singleton INSTANCE = new Singleton();

  
}


 

  
public static Singleton getInstance()

  
{

    
return SingletonHolder.INSTANCE;

  
}

 
}

 

另一个解决办法是在
getInstance()

方法声明中添加
synchronized

关键字:

 
public static synchronized Singleton getInstance()

提前考虑克隆预防

你仍然可以使用对象的
clone()

方法克隆对象,建立一个
Singleton

对象。要禁用这一功能,你需要禁用对象的克隆方法,这产生一个
CloneNotSupportedException

例外。

     
public Object clone() throws

CloneNotSupportedException {

        
throw new CloneNotSupportedException();

}

考虑使
singleton


类位于最后

你可能希望将
Singleton

类放在最后,以避免
Singleton

的子类造成其它问题。

不要忘记垃圾收集

根据不同的执行,你的
Singleton

类和它的所有数据可能被当作垃圾收集。因此,在应用程序运行时,你必须保证存在一个
Singleton

类的实时引用。

结论

Singleton

模块得到广泛地使用,并证实可用于软件设计。虽然这个模式并非
Java

专有,但它已成为
Java

编程的一个典型应用。尽管这个模式相当简单,但还是要记住我在本文中描述的
Singleton

模式的限制。

Peter V. Mikhalenko


是一名通过
Sun


认证的专家,现在任德意志银行商业顾问。

抱歉!评论已关闭.