饿汉式:
package com.anlysqx.pattern.factory.Singleton;
public class Singleton {
//类初始化时立即加载这个对象
//由于加载类时,天然的是线程安全的
private static Singleton singleton = new Singleton();
private Singleton(){}
//方法没有同步,调用效率高
public static Singleton getInstance(){
return singleton;
}
public void info(){
System.out.println("有了singleton对象");
}
}
懒汉式:
package com.anlysqx.pattern.factory.Singleton;
public class Singleton2 {
//类初始化时,不初始化这个对象,延迟加载,真正调用的时候再创建
private static Singleton2 singleton2;
//私有化构造器
private Singleton2(){}
//方法同步,调用效率低
public static synchronized Singleton2 getInstance(){
if (singleton2 == null){
singleton2 = new Singleton2();
}
return singleton2;
}
public void info(){
System.out.println("singleton2 info");
}
}
单例模式的拓展: 有限多例模式:
package com.anlysqx.pattern.factory.Singleton;
import java.util.ArrayList;
import java.util.List;
public class Singleton3 {
private static List<Singleton3> list;
static {
list = new ArrayList<Singleton3>();
for(int i=0;i<5;i++){
list.add(new Singleton3());
}
}
private Singleton3(){}
public static Singleton3 getRandomInstance(){
return list.get((int)Math.random()*5);
}
public static Singleton3 getInstanceByIndex(int index){
return list.get(index);
}
public void info(){
System.out.println("singleton3 info...");
}
}
静态内部类实现懒汉模式,同时又天然的同步;
package com.anlysqx.pattern.factory.Singleton;
public class Singleton4 {
private static class SubSingleton{
//在外部类加载的时候不会加载内部类,除非是使用到了内部类
private static final Singleton4 instance = new Singleton4();
}
private Singleton4(){}
public static Singleton4 getInstance(){
return SubSingleton.instance;
}
public void info(){
System.out.println("外部类可以访问内部类的私有成员变量,坑爹不?");
System.out.println("singleton4 info...");
}
}
最简单的方式是使用枚举类的方式:
package com.anlysqx.pattern.factory.Singleton;
public enum Singleton5 {
INSTANCE;
public void otherOperation(){
System.out.println("other operation...");
}
}
调用的时候:
package com.anlysqx.pattern.factory.Singleton;
public class TestSingleton5 {
public static void main(String[] args) {
System.out.println(Singleton5.INSTANCE);
System.out.println(Singleton5.INSTANCE);
Singleton5.INSTANCE.otherOperation();
}
}
枚举类没有延长加载,线程安全调用效率高,并且可以天然的防止反射和反序列化。