定义:
保证一个类仅有一个实例,提供一个访问它的全局访问点。
单例模式有一下特点:
1、单例类只能有一个实例。
2、单例类必须自己自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
package Singleton;
/**
* 单列模式的七种写法
*
* @author Administrator
*
*/
// 1(懒汉,线程不安全):这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。
public class Singleton_0 {
private static Singleton_0 instance;
private Singleton_0() {
}
public static Singleton_0 getInstance() {
if (instance == null) {
instance = new Singleton_0();
}
return instance;
}
}
package Singleton;
/**
* 懒汉,线程安全):
* 这种写法能够在多线程中很好的工作,而且看起来它也具备很好的lazy loading,
* 但是,遗憾的是,效率很低,99%情况下不需要同步。
*/
public class Singleton_1 {
private static Singleton_1 instance;
private Singleton_1 (){}
public static synchronized Singleton_1 getInstance() {
if (instance == null) {
instance = new Singleton_1();
}
return instance;
}
}
package Singleton;
/**
* (饿汉):
*/
public class Singleton_2 {
private static Singleton_2 instance = new Singleton_2();
private Singleton_2 (){}
public static Singleton_2 getInstance() {
return instance;
}
}
package Singleton;
/**
* (饿汉,变种):
表面上看起来差别挺大,其实更第三种方式差不多,都是在类初始化即实例化instance。
* @author Administrator
*
*/
public class Singleton_3 {
private static Singleton_3 instance = null;
static {
instance = new Singleton_3();
}
private Singleton_3 (){}
public static Singleton_3 getInstance() {
return instance;
}
}
package Singleton;
/**
* 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,
* 它跟第三种和第四种方式不同的是(很细微的差别):第三种和第四种方式是只要Singleton类被装载了,
* 那么instance就会被实例化(没有达到lazy loading效果),
* 而这种方式是Singleton类被装载了,instance不一定被初始化。
* 因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,
* 从而实例化instance。
* 想象一下,如果实例化instance很消耗资源,我想让他延迟加载,
* 另外一方面,我不希望在Singleton类加载时就实例化,
* 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,
* 那么这个时候实例化instance显然是不合适的。
* 这个时候,这种方式相比第三和第四种方式就显得很合理。
* @author Administrator
*
*/
public class Singleton_4 {
private static class SingletonHolder {
private static final Singleton_4 INSTANCE = new Singleton_4();
}
private Singleton_4 (){}
public static final Singleton_4 getInstance() {
return SingletonHolder.INSTANCE;
}
}
package Singleton;
/**
* 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,
* 它跟第三种和第四种方式不同的是(很细微的差别):第三种和第四种方式是只要Singleton类被装载了,
* 那么instance就会被实例化(没有达到lazy loading效果),
* 而这种方式是Singleton类被装载了,instance不一定被初始化。
* 因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,
* 从而实例化instance。
* 想象一下,如果实例化instance很消耗资源,我想让他延迟加载,
* 另外一方面,我不希望在Singleton类加载时就实例化,
* 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,
* 那么这个时候实例化instance显然是不合适的。
* 这个时候,这种方式相比第三和第四种方式就显得很合理。
* @author Administrator
*
*/
public class Singleton_4 {
private static class SingletonHolder {
private static final Singleton_4 INSTANCE = new Singleton_4();
}
private Singleton_4 (){}
public static final Singleton_4 getInstance() {
return SingletonHolder.INSTANCE;
}
}
package Singleton;
/**
* (双重校验锁):
*
*
*
* @author Administrator
*
*/
public class Singleton_6 {
private volatile static Singleton_6 singleton;
private Singleton_6() {
}
public static Singleton_6 getSingleton() {
if (singleton == null) {
synchronized (Singleton_6.class) {
if (singleton == null) {
singleton = new Singleton_6();
}
}
}
return singleton;
}
}