1、一般单例,
优点:实现方式简单,十分可靠。
不足:无法对 instance 实例做延迟加载。如果单例的创建过程很慢,而由于 instance 是 static 的,
因此在 JVM加载单例类是,单例对象就会被建立。如果此时,这个单例类在系统中还扮演其它角色,
那么在任何使用这个单例的地方都会初始化这个
public class Singleton {
private Singleton() {
System.out.println("Singleton is create");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
public static void createString()
{
System.out.println("createString in Singleton");
}
public static void main(String[] args) {
// Singleton s1 = Singleton.getInstance();
// Singleton s2 = Singleton.getInstance();
//
// System.out.println(s1 == s2);
Singleton.createString();
}
}
2、延迟加载单例:
缺点:getInstance()方法必须是同步的,否则在多线程环境下,可能会导致多个实例被创建。
而且增加了 synchronized 关键词,在多线程环境下比较耗时。
public class LazySingleton {
private LazySingleton() {
System.out.println("LazySingleton is create");
}
// 静态成员变量初始值赋予 null, 确保系统启动时没有额外的负载
private static LazySingleton instance = null;
/**
* 必须有synchronized 关键词,否则多线程环境中,可能会导致多个实例被创建。
*
* @return
*/
public static synchronized LazySingleton getInstance() {
if( instance == null)
{
instance = new LazySingleton();
}
return instance;
}
}
3、序列化与反序列时实现单例:
public class SerSingleton implements Serializable
{
private SerSingleton()
{
System. out.println( "Singleton is create");
name = "SerSingletion";
}
private static SerSingleton instance = new SerSingleton();
public static SerSingleton getIntance() {
return instance ;
}
public static void creatString() {
System. out.println( "createString in Singleton");
}
/**
* 阻止生成新的实例,总是返回当前对象
* 该方法是关键,有该方法后 readObject()就会直接使用该方法,
* 从而实现了反序列化后还是单例。
*/
private Object readResolve()
{
return instance;
}
public static void main(String[] args)
{
SerSingleton s1 = null;
SerSingleton s = SerSingleton.getIntance();
try {
FileOutputStream fos = new FileOutputStream("SerSingleton.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(s);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("SerSingleton.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
s1 = (SerSingleton) ois.readObject();
ois.close();
System. out.println(s1 == s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}