单例类 JAVA设计模式_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 单例类 JAVA设计模式

单例类 JAVA设计模式

 2011/11/4 8:11:19  liqita  http://liqita.iteye.com  我要评论(0)
  • 摘要:基本概念Singleton是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或Socket连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.再举个例子,集合中的set中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到set,它只接受一个实例.JDK中正式运用了Singleton模式来实现set的这一特性,大家可以查看java.util
  • 标签:Java 模式 设计 设计模式


基本概念

Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.再举个例子,集合中的 set 中不能包含重复的元素,添加到set里的对象必须是唯一的,如果重复的值添加到 set,它只接受一个实例.JDK中正式运用了Singleton模式来实现 set 的这一特性,大家可以查看java.util.Collections里的内部静态类SingletonSet的原代码.其实Singleton是最简单但也是应用最广泛的模式之一,在 JDK 中随处可见.

实现 Singleton 模式的办法通常有三种.

一. 用静态方法实现 Singleton 这种方法是使用静态方法来监视实例的创建.为了防止创建一个以上的实例,我们最好把构造器声明为 private.

实现单例类:

public?class?Singleton?{?
??private?static?Singleton s;?
??private?Singleton(){};
??/**
???* Class method to access the singleton instance of the class.
???*/

??public?static?Singleton?getInstance()?{
????if?(s?==?null)
??????s?=?new?Singleton();
????return?s;
??}
}
// 测试类

class?singletonTest?{
??public?static?void?main(String[]?args)?{
????Singleton s1?=?Singleton.getInstance();
????Singleton s2?=?Singleton.getInstance();
????if?(s1==s2)
??????System.out.println("s1 is the same instance with s2");
????else
??????System.out.println("s1 is not the same instance with s2");
??}
}

上述实现不是线程安全的!一下实现是线程安全的:

public class Singleton{
private volatile static Singleton uniqueInstance;
private Singleton(){}//构造函数是私有的 可以防止外界痛过new来初始化
public static Singleton getInstance(){
if(uniqueInstance==null){
?????? synchronized(Singleton.class){
??????????? if(uniqueInstance==null){
??????????????? uniqueInstance=new Singleton()
???????????? }
??????? }

}
return uniqueInstance;
}
}
其中volatile关键字:该关键字修饰的变量每次被访问的时候,都会被强迫从共享内存中重读该变量的值
若该变量的值变化了 就会强迫线程将该值写入共享内存,这样在任何时刻,不同的线程总是看到变量的同
一个值。编译器和运行时会监视这个变量,它是共享的,而且对它的操作不会与其他的内存操作一起重排序.

?

二. 以静态变量为标志实现 Singleton 在类中嵌入一个静态变量做为标志,每次都在进入构造器的时候进行检查.

class SingletonException extends RuntimeException {
??public?SingletonException(String s)?{
????super(s);
??}
}
class Singleton {
??static boolean instance_flag?=?false;?// true?if?1 instance
??public?Singleton()?{
????if?(instance_flag)
??????throw new SingletonException("Only one instance allowed");
????else
??????instance_flag?=?true;?// set flag?for?1 instance
??}
}
// 测试类
public?class singletonTest {
??static?public?void main(String argv[])?{
????Singleton s1,?s2;
????// create one incetance--this?should always work
????System.out.println("Creating one instance");
????try {
??????s1?=?new Singleton();
????} catch?(SingletonException e)?{
??????System.out.println(e.getMessage());
????}
????// try to create another spooler?--should fail
????System.out.println("Creating two instance");
????try {
??????s2?=?new Singleton();
????} catch?(SingletonException e)?{
??????System.out.println(e.getMessage());
????}
??}
}

三. 用注册器机制来创建 Singleton 首先用集合中的Hashtable 和Enumeration来实现addItem(Object key, Object value),getItem(Object key), ,removeItem(Object key)等方法实现一个管理器,将key和value一一关联起来,客户程序员创建实例前首先用addItem方法进行注册,再用getItem方法获取实例.Hashtable中的key是唯一的,从而保证创建的实例是唯一的.用注册器机制来创建 Singleton模式的好处是易于管理,可以同时控制多个不同类型的Singleton 实例.

发表评论
用户名: 匿名