介绍:
主要思想:该模式涉及到唯一的类,由该类自己管理自己的实例对象,保证只有一个实例对象会被创建,对外提供一个访问其唯一对象的方法,直接访问该方法取实例对象,无需实例化。
意图:保证该类只有一个实例,并提供一个全局访问点。
何时使用:一个全局使用的类被频繁的创建和释放,控制实例条目,节省系统资源
关键代码:构造方法私有化
优点:
1、在内存中只有一个实例,节省内存开销,尤其是实例对象的频繁创建和销毁
2、避免对资源的多重占用
缺点:没有接口,不能继承,与单一指责原则相冲突,一个类应该只关心内部逻辑,而不关心外部实例如何来进行实例化。
使用:
懒汉式:
1、
package cn.domin.design.singleton;
/**
* 单例模式基础版
* 懒汉式(线程不安全)
* 严格上来说改模式不算单例模式,多线程情况下可能会产生多个实例。
* @author 98543
*/
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {};
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
2、
package cn.domin.design.singleton;
/**
* 懒汉式(线程安全)
* @author 98543
* 必须加锁才能保证单例,但99%情况下都不需要同步,效率很低。
*/
public class LazySoftSingleton {
private static LazySoftSingleton instance;
private LazySoftSingleton() {};
public static synchronized LazySoftSingleton getInstance() {
if (instance == null) {
instance = new LazySoftSingleton();
}
return instance;
}
}
饿汉式:
1、
package cn.domin.design.singleton;
/**
* 饿汉式(线程安全)
* @author 98543
* 线程安全,但容易产生垃圾对象。没有加锁,以内存换效率。
*/
public class HungerSingleton {
private static HungerSingleton instance = new HungerSingleton();
private HungerSingleton() {};
public static HungerSingleton getInstance() {
return instance;
}
}
2、
package cn.domin.design.singleton;
/**
* 静态内部内实现
* 与 HungerSingleton唯一不同的是提供懒加载
* @author 98543
*/
public class StaticOwnSingleton {
private static class SingletonHolder{
private static final StaticOwnSingleton instance = new StaticOwnSingleton();
}
private StaticOwnSingleton() {};
public static StaticOwnSingleton getInstance() {
return SingletonHolder.instance;
}
}
DCL:
package cn.domin.design.singleton;
/**
* 双重锁机制(DCL)
* @author 98543
*
*/
public class DCLSingleton {
private static DCLSingleton instance;
private DCLSingleton() {};
public static DCLSingleton getInstance() {
if (instance == null) {
synchronized (DCLSingleton.class) {
if (instance == null) {
instance = new DCLSingleton();
}
}
}
return instance;
}
public static void main(String[] args) {
EnumSingleton.INSTANCE.getOtherMethod();
}
}
enum:
package cn.domin.design.singleton;
/**
* 枚举方式实现,最佳解决方案,反射和反序列化也无法创建。
* @author 98543
*
*/
public enum EnumSingleton {
INSTANCE;
public void getOtherMethod() {
}
}
总结:
1:严格来说,不算单例模式
2:支持懒加载,以安全换效率,线程安全
3:不支持懒加载,可能会造成垃圾,线程安全
4:支持懒加载,但只能在静态域情况下使用,线程安全
5:适用于特殊情况下使用,多线程下高性能,线程安全
6:推荐使用的方法,无解原理待查看enum实现单例模式