淘宝建站服务,热点新闻头条,使用c#语言建设网站优点,wordpress网站排行一、概念
单例设计模式#xff08;Singleton Design Pattern#xff09;#xff1a;一个类只允许创建一个对象#xff08;或者实例#xff09;#xff0c;那这个类就是一个单例类。
优点#xff1a;在内存里只有一个实例#xff0c;减少了内存的开销#xff0c;避免…一、概念
单例设计模式Singleton Design Pattern一个类只允许创建一个对象或者实例那这个类就是一个单例类。
优点在内存里只有一个实例减少了内存的开销避免一个全局使用的类频繁地创建与销毁。
缺点没有接口不能继承与开闭职原则冲突。
使用场景有些数据在系统中只应该保存一份就比较适合设计为单例类。比如系统的配置信息类。除此之外我们还可以使用单例解决资源访问冲突的问题。
二、实现
1、步骤
构造方法定义为私有方法。定义一个私有的类静态实例。提供一个公有的获取实例的静态方法。
2、实现方式
饿汉模式
public class HungryModeSingleton {private static final HungryModeSingleton mInstance new HungryModeSingleton();private HungryModeSingleton() {}public static HungryModeSingleton getInstance() {return mInstance;}
}总结在类加载的时候就对实例进行初始化没有线程安全问题获取实例的静态方法没有使用同步调用效率高但是没有使用懒加载如果该实例从始至终都没被使用过则会造成内存浪费。
懒汉模式
public class LazyModeSingleton {private static LazyModeSingleton mInstance;private LazyModeSingleton () {}public static synchronized LazyModeSingleton getInstance() {if (mInstance null){mInstance new LazyModeSingleton();}return mInstance;}
}总结上面是线程安全的懒汉模式在第一次使用的时候才进行初始化达到了懒加载的效果但是这种写法每次获取实例都要进行同步加锁因此在频繁获取对象的时候效率较低。
双检锁/双重校验锁DCL即 double-checked locking public class DCLModeSingleton {private static volatile DCLModeSingleton mInstance;private DCLModeSingleton () {}public static synchronized DCLModeSingleton getInstance() {if (mInstance null){synchronized (DCLModeSingleton.class){if (mInstance null){mInstance new DCLModeSingleton();}}} return mInstance; }
} 总结双重校验锁方式在第一次使用的时候才进行初始化达到了懒加载的效果。并且只有第一次进行初始化才进行同步因此不会有效率方面的问题。 在上面的例子中DCLModeSingleton的实例使用了volatile关键字进行修饰主要是为了解决在一些JDK低版本上有指令重排的问题。 指令重排问题当线程A执行到9行的时候线程B执行到6行CPU在进行对象创建的时候内部会在保证不影响最终结果的前提下对指令进行重新排序不影响最终结果只是针对单线程。例如 创建对象步骤分配空间- 初始化对象 -设置mInstance指向。 指令重排后分配空间- 设置mInstance指向 -初始化对象 此时线程B执行到第6行发现mInstance不为空但是对象并没有初始化完成会出现问题但是概率较低。 使用volatile修饰符可以禁止指令重排防止出现该问题。 静态内部类
public class StaticModeSingleton {private StaticModeSingleton () {}private static class SingletonHolder{private static final StaticModeSingleton INSTANCE new StaticModeSingleton();}public static StaticModeSingleton getInstance() {return SingletonHolder.INSTANCE;}
}总结SingletonHolder 是一个静态内部类当外部类StaticModeSingleton被加载的时候并不会创建 SingletonHolder 实例对象。只有当调用 getInstance() 方法时SingletonHolder 才会被加载这个时候才会创建instance。instance 的唯一性、创建过程的线程安全性都由 JVM 来保证。所以这种实现方法既保证了线程安全又能做到延迟加载。
枚举
public enum Singleton {INSTANCE;//添加自己需要的操作public void doSomeThing() {}
}总结非懒加载线程安全可以避免反序列化重新创建对象。
3、实现方式优缺点对比
三、应用场景
网站计数器。应用程序的日志应用。Web项目中的配置对象的读取。数据库连接池。多线程池。
单例模式详解