随笔-11  评论-10  文章-8  trackbacks-0
关于Singleton的意图、动机之类去看书吧,这里只是讨论用java实现时需要注意的一些问题。

    在java的标准库中就有Singleton的实现--java.lang.Math,所有的方法都是静态方法,所有成员变量定义为static就一切 ok了。这样实际上根本不需要产生任何对象,所有的操作都是用类来实现的,确切的说是Zeroton,不过效果都一样,实现可能更简洁。log4j 中的LogManager也是用这种方法。这种方式实现的Singleton是Stateless的,可以看做是一个工具方法集.
    还有一种不常见的实现如下:
1class PrintSpooler
2{
3//this is a prototype for a printer-spooler class
4//such that only one instance can ever exist
5staticboolean
6instance_flag=false; //true if 1 instance
7public PrintSpooler() throws SingletonException
8{
9if (instance_flag)
10thrownew SingletonException("Only one spooler allowed");
11else
12instance_flag =true; //set flag for 1 instance
13System.out.println("spooler opened");
14}
15//-------------------------------------------
16publicvoid finalize()
17{
18instance_flag =false; //clear if destroyed
19}
20}

这种方法并不适合java(也许适合C++),因为垃圾回收的时机是无法控制的,对于一个不
再使用的对象由于没有被回收无法创建新的对象。

用的最多的方法是所谓的 static method.这种方式是Stateful的.在多线程的环境下要注意
同步问题.

1import java.io.FileInputStream;
2import java.io.IOException;
3import java.io.ObjectInputStream;
4import java.io.ObjectStreamException;
5import java.io.Serializable;
6
7/**
8 *
9*/
10
11/**
12 * @author bahamut
13 * @version 2005-9-22
14*/
15publicfinalclass MySingleton implements Serializable {
16
17privatestatic MySingleton instance =null;
18
19private String name;
20
21publicstaticsynchronized MySingleton getInstance() {
22if (instance ==null) {
23 instance =new MySingleton();
24 }
25return instance;
26 }
27
28// public Object clone() throws CloneNotSupportedException {
29// throw new CloneNotSupportedException();
30// }
31
32public String getName() {
33return name;
34 }
35
36private MySingleton() {
37 name =this.getClass().getName();
38 }
39
40 Object readResolve() throws ObjectStreamException {
41return getInstance();
42 }
43
44publicstaticvoid main(String arg[]) throws IOException,
45 ClassNotFoundException {
46
47// MySingleton singleton = MySingleton.getInstance();
48// ObjectOutputStream out = new ObjectOutputStream(new
49// FileOutputStream("out"));
50// out.writeObject(singleton);
51// out.close();
52
53 MySingleton deserializable =null;
54 ObjectInputStream in =new ObjectInputStream(new FileInputStream("out"));
55 deserializable = (MySingleton) in.readObject();
56 in.close();
57 System.out.println(deserializable.getName());
58 MySingleton singleton = MySingleton.getInstance();
59if (deserializable == singleton) {
60 System.out.println("They are same object");
61 } else {
62 System.out.println("They are not same object");
63 }
64 }
65}
66


有几点需要注意:

1。构造函数必须是private,这样才能防止通过new运算符创建对象,这样的类也必然是final的

2。getInstance() 方法必须是同步的,关于这里同步的问题

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html有详细的论述

3。最好实现 clone() 方法,防止通过clone()产生多个对象

4。对于实现Serializable接口的Singleton要实现 Object readResolve(),(详见jdk文档的
Serializable部分),可以防止由序列化而产生的多个对象。

5。其他可能产生多个对象的情况参见
http://java.sun.com/developer/technicalArticles/Programming/singletons/



posted on 2005-10-04 12:30 JBahamut 阅读(127) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: