单例模式(Singleton Pattern)确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
单例模式
单例模式的其他几种实现方式:
1、饿汉模式,线程安全
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
饿汉模式单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance() 方法。
2、懒汉模式,线程不安全
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作。
3、懒汉模式、线程安全:
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
虽然做到了线程安全,并且解决了多实例的问题,但是它并不高效。
因为在任何时候只能有一个线程调用 getInstance() 方法。但是同步操作只需要在第一次调用时才被需要,即第一次创建单例实例对象时。
4、双检锁/双重校验锁(DCL,即 double-checked locking)
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
5、静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
6、枚举
public enum Singleton{
INSTANCE;
}
总结:
一般来说,单例模式有五种写法:懒汉、饿汉、双重检验锁、静态内部类、枚举。上述所说都是线程安全的实现,上文中第一种方式线程不安全,排除。
一般情况下直接使用饿汉式就好了,如果明确要求要懒加载(lazy initialization)倾向于使用静态内部类。如果涉及到反序列化创建对象时会试着使用枚举的方式来实现单例。
参考资料
1、单例模式 | 菜鸟教程:
http://www.runoob.com/design-pattern/singleton-pattern.html
评论 (0)