1 单例模式
当一个类始终只允许创建一个实例,来减少系统的开销,这种类被称为单例类,这种模式被称为单例模式。
public class Singleton {
private Singleton() {
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
测试:
public class SingletonText {
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1==s2);
}
}
会在第一次访问该类的静态变量时初始化单例变量。
//加final关键词 避免子类实现方法破坏单例
public final class LazySingleton implements Serializable {
private static LazySingleton instance;
private LazySingleton() {
};
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
/**
* 反序列化还用这个对象,避免反序列化破坏单例
* @return
*/
public Object readResovle(){
return instance;
}
}
系统会在第一次调用getInstance方法时初始化单例,在高并发情况下可能会因为加了同步锁会影响到性能,
第三种模式,创建内部类,从内部类中获取已实例化好的静态变量,这样不会出现线程同步的问题。
public class StaticSingleton {
public static final Integer TEST_NUM=0;
private StaticSingleton() {
System.out.println("StaticSingleton->StaticSingleton()");
}
public static StaticSingleton getInstance() {
System.out.println("StaticSingleton->getInstance()");
return SingletonHolder.instance;
}
private static class SingletonHolder {
private static StaticSingleton instance = new StaticSingleton();
}
public static void main(String[] args) {
System.out.println(StaticSingleton.TEST_NUM);
StaticSingleton singleton=StaticSingleton.getInstance();
}
}
双从检查–错误的方案
public static class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
new Singleton();分为两步,第一步分配空间,第二步初始化,出现了重排序,导致其他线程获取到的事一个为初始化的对象。
基于Volatile的解决方案
public class SafeDoubleCheckedLocking {
private volatile static SafeDoubleCheckedLocking safeDoubleCheckedLocking;
public static SafeDoubleCheckedLocking getInstance(){
if(safeDoubleCheckedLocking==null){
synchronized (SafeDoubleCheckedLocking.class) {
if(safeDoubleCheckedLocking==null){
safeDoubleCheckedLocking=new SafeDoubleCheckedLocking();
}
}
}
return safeDoubleCheckedLocking;
}
}
基于Volatile的解决方案,除了可以对静态字段实现延迟初始化,还可以对实例字段实现延迟初始化。
摘自《Java并发编程的艺术》