??? 在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/