singleton 单例模式
单例模式是Java 中最常用的设计模式,也是面试中经常考察的。
标准版本
<图解设计模式> 书本上的示例代码,在class内有一个静态的变量直接赋值,在类加载的时候就初始化。缺点是有点浪费内存。因为类加载的时候是单线程,保证单例和线程安全。
public class Singleton1 {
private static Singleton1 singleton1 = new Singleton1();
private Singleton1() {
System.out.println("生成了一个实例.");
}
public static Singleton1 getInstance() {
return singleton1;
}
}
synchronized
延迟初始化实例,但是为了保证线程安全,getInstance需要加锁。
public class Singleton2 {
private static Singleton2 singleton2 = null;
private Singleton2() {
System.out.println("生成了一个实例.");
}
public static synchronized Singleton2 getInstance() {
if (singleton2 == null){
singleton2 = new Singleton2();
}
return singleton2;
}
}
双重校验
在方法上加锁synchronized,效率比较低,为了提高效率在getInstance方法内部加锁。锁住的代码范围越小,所等待的时间越少。
public class Singleton3 {
private static Singleton3 instance = null;
private Singleton3() {
System.out.println("生成了一个实例.");
}
public static Singleton3 getInstance() {
if (instance == null){
synchronized (Singleton3.class){
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
利用静态内部类
这种方式同样利用了 classloder 机制来保证初始化 instance 时只有一个线程,它跟标准版本不同的是:标准版本只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有显示通过调用 getInstance 方法时,才会显示装载 SingletonHolder 类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比标准版本就显得很合理。
public class Singleton4 {
private static class SingletonHolder {
private static final Singleton4 INSTANCE = new Singleton4();
}
private Singleton4 (){}
public static final Singleton4 getInstance() {
return SingletonHolder.INSTANCE;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。