单例模式是Java中最常见也是面试经常被问到的一种设计模式,本文详细列出了单例模式的几种写法。
懒汉式,双重校验锁
双重校验,多个线程下调用,只会创建一个实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Singleton {
private static Singleton instance;
private Singleton() { }
public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton();
} } } return instance; } }
|
饿汉式,线程安全
这种方法非常简单,实例被声明为final+static,第一次类加载到内存中就被初始化了,因此线程是安全的。
但种方法也是有缺点的,它不是一种懒加载模式,单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance()方法,所以它是典型的空间换时间,比较占内存。特别是一些需要依赖参数实例的,无法使用此方法。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance; } }
|
静态内部类
这种写法仍然使用JVM本身机制保证了线程安全问题;由于 InnerSingleton是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton {
private static class InnerSingleton { private static final Singleton INSTANCE = new Singleton(); }
private Singleton() { }
public static Singleton getInstance() {
return InnerSingleton.INSTANCE; } }
|
枚举
这种方法可以说是最简单的了。我们可以通过Singleton.INSTANCE访问实例,同时枚举是默认线程安全的。
1 2 3
| public enum Singleton { INSTANCE; }
|
总结
一般情况下推荐饿汉式和静态内部类这两种写法。
Read More