单例模式
来源:互联网 发布:淘宝类目销售比列 编辑:程序博客网 时间:2024/06/07 10:47
单例模式
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 –《JAVA与模式》
目前众所周知,单例模式主要有两种实现方式,一种是懒汉式,一种是饿汉式;其中懒汉式比较容易理解,但是作为饿汉式在实现的时可能有点麻烦。
饿汉式
饿汉式指的是在对象初始化的时候,那么就提供该对象的实例提供外部访问,无论外界是否真的需要该对象的实例。
public class EagerSingleton { private static final EagerSingleton eagerSingleton = new EagerSingleton(); /**私有化构造方法,不对外提供出去*/ private EagerSingleton () { } public static EagerSingleton getInstance() { return eagerSingleton; }}
懒汉式
懒汉式对比与饿汉式,他不会想饿汉式在初始化对象就实例化对象出来,与之不同的是在外部需要获取该对象的实例时,才初始化对象,这样做的好处就是在一定程度上节省的内存的消耗
public class LazySingleton { private static LazySingleton lazySingleton = null; /**私有化构造方法,不对外暴露*/ private LazySingleton() { } /** * 提供公共获取对象实例方法暴露出去 * 这里添加synchronized是为了在多线程环境下,保证依然提供单例出去; * 比如说A,B两个线程同时进入getInstance方法中,两个线程在判断lazySingleton是否为null时,都是true,那么就会提供两个不通过的实例化对象出去 * @return */ public static synchronized LazySingleton getInstance() { if (lazySingleton == null) { lazySingleton = new LazySingleton(); return lazySingleton; } return lazySingleton; }}
但是关于上面懒汉式的实现有一个瑕疵,就是每一次在去获取LazySingleton实例化是都需要上一个线程在获取结束之后,这样有一定的性能的问题,当然我们可以对这里的代码进行优化。
public class DoubleLockLazySingleton { /** * 这里使用volatile关键字,是为了保证doubleLockLazySingleton在多线程环境下保持一致性, * 所谓的一致性指的是N个线程在同时对doubleLockLazySingleton进行处理时,其中任意线程在对 * doubleLockLazySingleton已经进行了改变,那么其他线程可以马上获取到改变之后的doubleLockLazySingleton */ private static volatile DoubleLockLazySingleton doubleLockLazySingleton = null; private DoubleLockLazySingleton() { } public static DoubleLockLazySingleton getInstance() { // 初次判断doubleLockLazySingleton是否为空, if (doubleLockLazySingleton == null) { synchronized (DoubleLockLazySingleton.class) { // 再次判断是之前的判断是处于线程不安全的,所以需要再次判断,防止发生并发问题 if (doubleLockLazySingleton == null) { doubleLockLazySingleton = new DoubleLockLazySingleton(); return doubleLockLazySingleton; } } } return doubleLockLazySingleton; }}
这里笔者提供两种其他关于单例懒汉式的实现
- 内部类实现
public class InnerClassLazySingleton { private InnerClassLazySingleton() { } private static class InnerClassLazySingletonHolder { private static InnerClassLazySingleton InnerClassLazySingleton = new InnerClassLazySingleton(); } public static InnerClassLazySingleton getInstance() { /** * 这里之所以使用内部类的实现方式,是因为在JVM在加载类中的静态字段(或者静态代码块)是保证同步的, * 也就是说在N个线程在同步访问getInstance方法时,这里是去加载了InnerClassLazySingleton * 中的内部静态类InnerClassLazySingletonHolder,而加载内部静态类时又是同步的,那么就代表着 * 这里只有一个线程加载了InnerClassLazySingletonHolder,而且作为一个静态内部类而言,他在整个 * 系统中只会加载一次,他的生命周期是伴随着InnerClassLazySingleton而存在的 */ return InnerClassLazySingletonHolder.InnerClassLazySingleton; }}
- 枚举单例实现
public enum EnumSingleton { SINGLETON; public void doSomething() { // TODO }}
以上所有内容转自《JAVA与模式》之单例模式
0 0
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- 47-将多进程并发服务器改成 IO 复用
- leetcode 20
- 学习笔记之——Android中的Picasso实现圆形头像、圆角图片工具类
- mybatis中<where>标签、<set>标签、<trim>标签、<sql>标签、<foreach>标签的使用
- Activiti数据库配置
- 单例模式
- 【Shell】快速追踪哪些文件包含某个关键词
- Linux ALSA声卡驱动之二:声卡的创建
- Tensorflow读取数据1
- java 求阶乘
- 欢迎使用CSDN-markdown编辑器
- STM32 boot跳转到APP的Jump_Address()分析
- cssiot_李_TCP建立流程_讲稿
- sun.misc.BASE64Encoder找不到jar包的解决方法