彻底理解单例模式
一、单例(Singleton)模式
单例模式的要点有三个:一是某个类只能有一个实例,二是它必需自行创建这个实例,三是它必须向整个系统自行提供这个实例.
二、典型单例类
下面是一个它的实现:
/* * 典型单例类,不能被继承 */public class Singleton { /* * Singleton 类自己将自己实例化 * 此该类被加载时,静态变量 instance 会通过调用私有构造函数被实例化 */ private static final Singleton instance = new Singleton(); /* * 私有构造函数防止此类被外界调用而产生多个实例 * 由于构造函数私有的类,所以不能被继承 */ private Singleton() {} public static Singleton getInstance() { return instance; }}
/* * 延迟单例类,不能被继承 */public class Singleton { /* * Singleton 类自己将自己实例化 * 此该类被加载时,静态变量 instance 会通过调用私有构造函数被实例化 */ private static Singleton instance = null; /* * 私有构造函数防止此类被外界调用而产生多个实例 */ private Singleton() {} /* * synchronized 同步化以处理多线程环境 */ public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; }}
import java.util.HashMap;public class Singleton {// 容器用来存放对应关系 private static HashMap sinRegistry = new HashMap(); private static Singleton s = new Singleton(); // 受保护的构造函数 protected Singleton() {} public static Singleton getInstance(String name) { if(name == null) name = "Singleton"; if(sinRegistry.get(name) == null) { try { sinRegistry.put(name , Class.forName(name).newInstance()); } catch(Exception e) { e.printStackTrace(); } } return (Singleton)(sinRegistry.get(name)); }}public class SingletonChild1 extends Singleton { public SingletonChild1() {} public static SingletonChild1 getInstance() { return (SingletonChild1) Singleton.getInstance("SingletonChild1"); }}
public final class Singleton implements Serializable {private static final long serialVersionUID = 1L;private Singleton() {}private static final Singleton instance = new Singleton();public static Singleton getInstance() {return instance;}private Object readResolve() throws ObjectStreamException {return instance;}}
import java.io.Serializable;import java.io.ObjectStreamException;public class Singleton implements Serializable { private static final long serialVersionUID = 1L; private static Singleton instance; private Integer counter = new Integer(0); private Singleton() { counter = 0; } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } public synchronized int getNext() { return ++counter; }/* 反序列保证private Object readResolve() throws ObjectStreamException {return instance;}*/}import java.io.IOException;import java.io.FileNotFoundException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;public class Test { public static void main(String [] args) throws FileNotFoundException, IOException, ClassNotFoundException{ Singleton singleton = Singleton.getInstance(); // 第一个对象 System.out.println(singleton.getNext()); // 打印 1 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.obj")); oos.writeObject(singleton); // 将该对象写在 object.obj 文件中 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.obj")); Singleton singleton2 = (Singleton)ois.readObject(); // 再读出来 System.out.println(singleton.getNext()); // 打印 2System.out.println(singleton.getNext()); // 打印 3 System.out.println(singleton2.getNext()); // 打印 3 or 2 取决于是否实现了 readResolve() 方法 System.out.println(singleton2 == singleton); // 打印 true or false 取决于是否实现了 readResolve() 方法 }}