设计模式-单例模式
使用场景
- 使用场景:
- 要求生产唯一序列号。
- WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
- 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
懒汉模式(线程不安全、不建议使用)
public class Singleton_01 {
private static Singleton_01 instance;
private Singleton_01() {
}
public static Singleton_01 getInstance(){
if (null != instance) {
return instance;
}
return new Singleton_01();
}
}
懒汉模式(线程安全、不建议使用)
public class Singleton_02 {
private static Singleton_02 instance;
private Singleton_03 (){}
public static synchronized Singleton_02 getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步
双重校验锁模式(线程安全、可以使用)
public class Singleton_03 {
private volatile static Singleton_03 singleton;
private Singleton_03 (){}
public static Singleton_03 getSingleton() {
if (singleton == null) {
synchronized (Singleton_03.class) {
if (singleton == null) {
singleton = new Singleton_03();
}
}
}
return singleton;
}
}
- 这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
饿汉模式(最简单、项目中最实用的模式、线程安全)
public class Singleton_04 {
private static Singleton_04 instance = new Singleton_04();
private Singleton_04() {
}
public static Singleton_04 getInstance() {
return instance;
}
}
- 这个是以空间换时间的解决方案,也是最简单的方式,在内存足够大的情况下推荐使用这种方式。
静态内部类模式(线程安全、明确实现 lazy loading 效果)
public class Singleton_05 {
private static class SingletonHolder {
private static final Singleton_05 INSTANCE = new Singleton_05();
}
private Singleton_05 (){}
public static final Singleton_05 getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 即保证了懒加载又解决了加锁耗费性能的问题。
- JVM可以保证多线程并发访问的正确性。
枚举模式(最佳方法、涉及到反序列化创建对象)
public enum Singleton_06 {
INSTANCE;
public static final Singleton_06 getInstance() {
return Singleton_06.INSTANCE;
}
}
- 它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化