摘要:第二种懒汉式线程不安全对象为空才去实例化懒汉式是在使用的时候才会去加载,不过当多次同时去加载的时候就会存在线程安全问题。
单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类,通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
第一种:饿汉式
public class SingleEasy { private SingleEasy(){ } //类初始化的时候就已经加载 private static SingleEasy singleEasy=new SingleEasy(); public static SingleEasy getInstance(){ return singleEasy; } }
饿汉式的话不存在多线程同步加载的问题,类初始化时就已经加载,做不到使用的时候才加载。
第二种:懒汉式(线程不安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static SingleNotEmptyEasy getInstance(){ //对象为空才去实例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; } }
懒汉式是在使用的时候才会去加载,不过当多次同时去加载的时候就会存在线程安全问题。
第三种:懒汉式(线程安全)
public class SingleNotEmptyEasy { private static SingleNotEmptyEasy singleNotEmptyEasy; private SingleNotEmptyEasy(){ } public static synchronized SingleNotEmptyEasy getInstance(){ //对象对空才去实例化 if(singleNotEmptyEasy==null){ singleNotEmptyEasy=new SingleNotEmptyEasy(); } return singleNotEmptyEasy; } }
就是在第二种的getInstance方法上面加了一个同步锁synchronized,每次在使用加载的时候都会先去校验,如果已经有在加载了,就不会去加载,而是要等前面的加载完了,才会去加载,这样线程安全,但是每次都去校验synchronized会造成效率的下降。
第四种:DCL
public class DCLSingle { private volatile static DCLSingle dclSingle; private DCLSingle(){ } public static DCLSingle getInstance(){ if(dclSingle==null){ synchronized (DCLSingle.class){ if(dclSingle==null){ dclSingle=new DCLSingle(); } } } return dclSingle; } }
DCL模式的不同是没有将同步锁加载方法上,而是加在代码块里面,如果单例对象不为空就直接返回,如果为空就会走到加了同步锁的代码块中,还会进行第二次校验,这样子提高了效率,同时也保证了线程的安全,这种模式还涉及到一个java的关键字volatile,加了volatile,可以保证无论何时读取这个变量,都是读到内存中最新的值,无论何时写这个变量,都可以立即写到内存中。
第五种:内部类模式
public class InnnerClassSingle { private InnnerClassSingle(){ } private static class SingleHolder{ private static InnnerClassSingle innnerClassSingle=new InnnerClassSingle(); } public static InnnerClassSingle getInstance(){ return SingleHolder.innnerClassSingle; } }
内部类模式是一种比较优雅的饿汉式,它是在InnnerClassSingle内中再建一个SingleHolder内部类,在内部类中创建一个InnnerClassSingle对象,通过内部类调用加载实例化,这样子不会随着类的加载的而实例化,做到了使用的时候才实例化。
第六种:枚举模式
public enum EnumManager { SDCardManager(10){ @Override public EnumManager getSingle() { return SDCardManager; } } , HttpManager(1){ @Override public EnumManager getSingle() { return HttpManager; } }; public abstract EnumManager getSingle(); private EnumManager(int type){ } }
这里需要注意的是枚举的构造方法是私有的,变量的声明要在构造方法之前。
欢迎加入学习交流群569772982,大家一起学习交流。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/70505.html
摘要:总结单例是运用频率很高的模式,因为客户端没有高并发的情况,选择哪种方式并不会有太大的影响,出于效率考虑,推荐使用和静态内部类实现单例模式。 单例模式介绍 单例模式是应用最广的模式之一,也可能是很多人唯一会使用的设计模式。在应用单例模式时,单例对象的类必须保证只用一个实例存在。许多时候整个系统只需要一个全局对象,这样有利于我么能协调整个系统整体的行为。 单例模式的使用场景 确保某个类有且...
摘要:不符合设计模式中的单一职责的概念。引入代理实现单例模式引入代理实现单例模式的特点我们负责管理单例的逻辑移到了代理类中。的单例模式对比在以上的代码中实现的单例模式都混入了传统面向对象语言的特点。 声明:这个系列为阅读《JavaScript设计模式与开发实践》 ----曾探@著一书的读书笔记 1.单例模式的特点和定义 保证一个类仅有一个实例,并且提供一个访问它的全局访问点。 2.传统面向对...
摘要:如果需要防范这种攻击,请修改构造函数,使其在被要求创建第二个实例时抛出异常。单例模式与单一职责原则有冲突。源码地址参考文献设计模式之禅 定义 单例模式是一个比较简单的模式,其定义如下: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 或者 Ensure a class has only one instance, and provide a global point of ac...
摘要:在设计模式一书中,将单例模式称作单件模式。通过关键字,来保证不会同时有两个线程进入该方法的实例对象改善多线程问题为了符合大多数程序,很明显地,我们需要确保单例模式能在多线程的情况下正常工作。 在《Head First 设计模式》一书中,将单例模式称作单件模式。这里为了适应大环境,把它称之为大家更熟悉的单例模式。 一、了解单例模式 1.1 什么是单例模式 单例模式确保一个类只有一个实例,...
阅读 2393·2021-11-25 09:43
阅读 1149·2021-09-07 10:16
阅读 2576·2021-08-20 09:38
阅读 2917·2019-08-30 15:55
阅读 1390·2019-08-30 13:21
阅读 859·2019-08-29 15:37
阅读 1407·2019-08-27 10:56
阅读 2076·2019-08-26 13:45