關(guān)于Singleton的意圖、動機之類去看書吧,這里只是討論用java實現(xiàn)時需要注意的一些問題。
???
在java的標準庫中就有Singleton的實現(xiàn)--java.lang.Math,所有的方法都是靜態(tài)方法,所有成員變量定義為static就一切
ok了。這樣實際上根本不需要產(chǎn)生任何對象,所有的操作都是用類來實現(xiàn)的,確切的說是Zeroton,不過效果都一樣,實現(xiàn)可能更簡潔。log4j
中的LogManager也是用這種方法。這種方式實現(xiàn)的Singleton是Stateless的,可以看做是一個工具方法集.
??? 還有一種不常見的實現(xiàn)如下:
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++),因為垃圾回收的時機是無法控制的,對于一個不
再使用的對象由于沒有被回收無法創(chuàng)建新的對象。
用的最多的方法是所謂的 static method.這種方式是Stateful的.在多線程的環(huán)境下要注意
同步問題.
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。構(gòu)造函數(shù)必須是private,這樣才能防止通過new運算符創(chuàng)建對象,這樣的類也必然是final的
2。getInstance() 方法必須是同步的,關(guān)于這里同步的問題
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html有詳細的論述
3。最好實現(xiàn) clone() 方法,防止通過clone()產(chǎn)生多個對象
4。對于實現(xiàn)Serializable接口的Singleton要實現(xiàn) Object readResolve(),(詳見jdk文檔的
Serializable部分),可以防止由序列化而產(chǎn)生的多個對象。
5。其他可能產(chǎn)生多個對象的情況參見
http://java.sun.com/developer/technicalArticles/Programming/singletons/
posted on 2005-10-04 12:30
JBahamut 閱讀(134)
評論(0) 編輯 收藏