定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供整个实例。
使用场景:
1.需要频繁实例化然后销毁的对象
2.创建对象时耗时或资源消耗过多,但又经常使用的对象
3.资源共享的情况下,避免由于资源操作导致的性能或损耗等
4.控制资源的情况下,方便资源之间的相互通信
如:任务管理器、回收站、servlet(默认单例)、spring(mvc)
(默认单例)、连接池、线程池、读取配置对象、应用日志
单例创建方式
1.饿汉式:类初始化时,会立即加载该对象,线程安全,调用效率高。
2.懒汉式:类初始化时不会加载该对象,真正需要使用的时候才会创建该对象,具有懒加载的功能。
懒汉式的优点是单例只有在使用的时候才会被实例化,在一定程度上节约了资源;缺点是第一次加载时需要及时进行实例化,反应稍慢,最大的问题是每次调用getInstance()方法都进行同步,造成不必要的同步开销。这种模式一般不建议使用
3. 双重检测锁方式 (因为JVM本质重排序的原因,可能会初始化多次,不推荐使用)
具体原因及DCL失效问题,请参考 https://mp.csdn.net/postedit/80179698
4. 静态内部方式:结合了懒饿汉式的优点,真正需要对象的时候才会加载,加载类是线程安全的。
DCL虽然在一定程度上解决了资源消耗、多余的同步、线程安全等问题,但它会在某些情况下出现失效问题。这个问题被称为双重检查锁定(DCL)失效,在《Java并发编程》一书的最后谈到了这个问题,并指出这种"优化"是丑陋的,不赞成使用。而建议使用如下代码替代
5. 枚举单例:
在《Effective Java》中有提到,因为其功能完整、使用简洁、无偿地提供了序列化机制、在面对复杂的序列化或者反射攻击时仍然可以绝对防止多次实例化等优点,单元素的枚举类型被作者认为是实现Singleton的最佳方法。
防止反射攻击
1.枚举防止反射漏洞攻击
2. 懒汉式防止反射漏洞攻击