面试题2:单例模式Singleton
首先,单例模式使类在程序生命周期的任何时刻都只有一个实例,
然后,单例的构造函数是私有的,外部程序如果想要访问这个单例类的话,
必须通过 getInstance()来请求(注意是请求)得到这个单例类的实例。
1、饿汉式
package singleton;
/**
* 单例模式保证一个类仅有一个实例,同时这个类还必须提供一个访问该类的全局访问点。
*
* 饿汉式:new之后,便创建对象,以后不再改变,此种方式天生线程安全的
*/
public class SingletonDemo1 { //定义一个私有的静态全局变量来保存该类的唯一实例
private static SingletonDemo1 instance=new SingletonDemo1();
//构造函数必须是私有的,这样在外部便无法使用 new 来创建该类的实例
private SingletonDemo1(){
} //定义一个全局访问点 ,设置为静态方法 ,则在类的外部便无需实例化就可以调用该方法
public static SingletonDemo1 getInstance(){
return instance;
} }
2、懒汉式
package singleton;
/**
* 懒汉式:在需要的时候创建对象
* if()判断,保证线程的安全性
* @author Don
*
*/
public class SingletonDemo2 { private static SingletonDemo2 instance;
private SingletonDemo2(){
} //ͬ多线程访问时,当有一个线程访问时就加锁,防止产生多个实例
public static synchronized SingletonDemo2 getInstance(){
if(instance==null){
instance=new SingletonDemo2();
}
return instance;
}
}
3、静态内部类(结合了前两种的优势)
package singleton;
/**
* 静态内部类:兼备了高效调用和延迟加载的优势
* @author Don
*
*/
public class SingletonDemo3 { //只有真正调用getInstance(),才会加载静态内部类。加载类时是线程安全的。instance是static final类型
//保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性
private static class SingletonClassInstance{
private static final SingletonDemo3 instance=new SingletonDemo3();
}
private SingletonDemo3(){
} public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
} }
饿汉式和懒汉式区别:
从名字上来说,饿汉和懒汉,
饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,
而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
另外从以下两点再区分以下这两种方式:
1、线程安全:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,
懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别。
2、资源加载和性能:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。
至于1、2、3这三种实现又有些区别,
第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,
第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗
第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。
什么是线程安全?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。
面试题2:单例模式Singleton的更多相关文章
- 【剑指offer】面试题 2. 实现 Singleton 模式
面试题 2. 实现 Singleton 模式 题目:设计一个类,我们只能生成该类的一个实例. 单例模式:确保一个类只有一个实例,并提供了一个全局访问点. Java 实现 1.饿汉模式 //饿汉模式 p ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 【白话设计模式四】单例模式(Singleton)
转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...
- ooad单例模式-Singleton
单例模式Singleton 主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 比如建立目录 ...
- iOS单例模式(Singleton)写法简析
单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...
- 浅谈设计模式--单例模式(Singleton Pattern)
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
- 设计模式之——单例模式(Singleton)的常见应用场景
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...
- 设计模式之单例模式(Singleton Pattern)
单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...
- 设计模式(4) -- 单例模式(Singleton)
设计模式(4) -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...
- IOS单例模式(Singleton)
IOS单例模式(Singleton) 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模 ...
随机推荐
- aws相关文档
使用 IAM 角色授予对 Amazon EC2 上的 AWS 资源的访问权 https://docs.aws.amazon.com/zh_cn/sdk-for-java/v1/developer-gu ...
- 如何解决Visual Studio2010 编译时提示系统找不到指定文件问题
前一段时间,开始使用vs2010编写程序,可是在编译的时候总是报错,提示系统找不到指定文件,导致无法正常运行程序,花了好久时间终于找到原因解决,是因为常规的输出目录 要与链接的常规的输出文件要相对应. ...
- FOJ-1058-粗心的物理学家
题目:粗心的物理学家 代码: #include<stdlib.h> #include<iostream> #include<cstdio> using namesp ...
- UVa 1471 防线
https://vjudge.net/problem/UVA-1471 题意:给出一个序列,删除一个连续子序列,使得剩下的序列中有一个长度最大的连续递增子序列,输出个数. 思路:首先可以计算出以i结尾 ...
- html 画圆
<html> <head> <script type = "text/javascript" src = "https://d3js.org ...
- yaml 文件保存
with open(mpath, "w") as f: yaml.safe_dump(yaml_dict,f,encoding='utf-8', allow_unicode=Tru ...
- Qt5_QString_测试
ZC: 下面的测试效果看,可以只是用 “QString.isEmpty()” 或者 “QString == ""”来判断 QString是否为 空或者NULL . 1. 1.1. ...
- XML_CPP_资料_libxml2库函数详解
http://blog.csdn.net/hanchaoman/article/details/42557195 许多事物符合80/20法则,libxml中也是20%的函数提供了80%的功能.下面的列 ...
- BN层
论文名字:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift 论 ...
- spring boot:创建一个简单的web(maven web project)
1.新建一个maven web project; 2.在pom.xml文件中添加相应的依赖包: 3.新建一个HelloController请求控制类: 4.编写index.jsp页面: 5.编写启动类 ...