Chinaunix首页 | 论坛 | 博客
  • 博客访问: 715132
  • 博文数量: 147
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 10:36
文章分类

全部博文(147)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(110)

我的朋友

分类: Java

2008-08-24 10:17:43

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 实例.

 

 

阅读(1110) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~