单例模式(Singleton)实现方式及比较——JAVA设计模式

单例模式:这种模式涉及到一个单一的类,该类自己创建一个且只创建一个自己的对象。这个类提供一种访问其唯一对象的方式,可直接访问,不需要再实例化。

单例模式的几种实现方式:

懒汉式:到用的时候才会实例化。(不推荐使用)

线程不安全:

缺点:多线程不安全,多线程不能正常使用。

public class Singleton {
	private static Singleton instance = null;
	
	private Singleton() { }
	
	public static Singleton getInstance() {
		if(null == instance) {
			instance = new Singleton();
		}
		
		return instance;
	}
}

线程安全:

优点:多线程安全;第一次调用才初始化,避免内存浪费。

缺点:加synchronized锁,效率低下。

public class Singleton {
	private static Singleton instance = null;
	
	private Singleton() { }
	
	public static synchronized Singleton getInstance() {
		if(null == instance) {
			instance = new Singleton();
		}
		
		return instance;
	}
}

饿汉式:类加载时候实例化。(推荐使用)

优点:多线程安全;没有加锁,执行效率会提高。

缺点:类加载时就初始化,浪费内存;容易产生垃圾对象。

public class Singleton {
	private static final Singleton instance = new Singleton();
	
	private Singleton() { }
	
	public static Singleton getInstance() {
		return instance;
	}
}

双检锁/双重校验锁(推荐使用)

优点:多线程安全;第一次调用才初始化,避免内存浪费;双锁机制,多线程保持高性能。

public class Singleton {
	private volatile static Singleton instance = null;
	
	private Singleton() { }
	
	public static Singleton getInstance() {
		if(null == instance) {    
			synchronized (Singleton.class) {
				if(null == instance) {    
					instance = new Singleton();
				}
			}
		}
		
		return instance;
	}
}

登记式/静态内部类(推荐使用)

优点:多线程安全;第一次调用才初始化,避免内存浪费;和双检锁方式效果相同,但实现比双检锁简单。

与饿汉式相比,饿汉式是类加载时就初始化,而该方式是类加载时不会初始化,直到显示调用getInstance()方法时才会初始化。

public class Singleton {
	private static class SingletonHolder {
		private static final Singleton instance = new Singleton();
	}
	
	private Singleton() { }
	
	public static final Singleton getInstance() {
		return SingletonHolder.instance;
	}
}

枚举(推荐使用)

优点:简洁,自动支持序列化机制,绝对防止多次实例化。

public enum Singleton {
	INSTANCE;
	
	public void whateverMethod() {
		
	}
}	

使用场合总结:一般情况下:

  1. 不建议使用懒汉方式;
  2. 推荐使用饿汉方式;
  3. 只有在要明确lazy loading效果时,才会使用登记式/静态内部类方式;
  4. 如果涉及到序列化创建对象时,可以尝试使用枚举方式;
  5. 如果有其它特殊需求,可以考虑使用双检锁方式。
参考资料: 单例模式

你可能感兴趣的:(Java设计模式,单例模式,Singleton,设计模式,Java)