单例模式通用代码,非延迟加载,饿汉式单例,是线程安全的初始化方法,推荐这种方法:
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton() {
// 初始化代码
}
public static Singleton getSingleton() {
return singleton;
}
// 类中其他方法,尽量是static?why
public static void doSomething() {
}
}
单例模式的有点先不讲了,主要讲缺点:
1,单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码外无其他途径。
2,单例模式对测试不利,在并发开发中,如果单例没有开放完是不能测试的,因为不能mock一个单例
3,单例与单一职责原则有冲突
单例模式使用场景:
1,要求生成唯一序列号的环境
2,在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的。
3,创建一个对象开销过大,需要耗费资源过多,例如访问IO和数据库资源
4,需要定义大量的静态常量和静态方法如工具类的环境,可以采用单例模式,当然,这种情况下也可以直接声明为static的方式。
最佳实践:
使用单例模式需要注意的一点就是JVM的垃圾回收机制,如果我们的一个单例对象在内存中长久不使用,JVM就认为这个对象是一个垃圾,在CUP资源空闲的情况下该对象会被清理掉,下次调用的时候会产生一个全新的对象。如果我们在应用中使用单例类作为有状态值的管理,则会出现恢复原状的情况,有两种办法可以解决这种问题:
1,由容器管理单例生命周期
JavaEE容器或者框架级容器比如spring可以让对象长久驻留在内存中
2,状态随时记录
可以使用异步记录方式,或者使用观察者模式记录状态的变化,写入文件或写入数据库,确保即使单例重新初始化也可以从资源环境获得销毁前的数据,避免应用数据丢失
本人博客已搬家,新地址为:http://yidao620c.github.io/