设计模式之单例模式 Singleton实现
饿汉式
- 饿汉式单例模式,static变量会在类装载时初始化,此时也不会涉及多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题,
因此可以省略synchronized关键字
- 问题:如果只是加载本类,而不是要调用getInstance(),甚至永远没有调用,则会造成资源浪费
public class SingletonDemo1 {
//类初始化时,立即加载这个对象(没有延时加载的优势),,记载类时,天然的是线程安全的
private static SingletonDemo1 instance = new SingletonDemo1();
private SingletonDemo1(){
};
//方法没有同步,效率高
public static SingletonDemo1 getInstance(){
return instance;
}
}
懒汉式
- Lazy Load,延时加载,真正用到的时候再加载
- 每次都得使用同步,synchronized,效率就底下了。
public class SingletonDemo2 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo2 instance ;
private SingletonDemo2(){
};
//方法同步,效率低
public static synchronized SingletonDemo2 getInstance(){
if(instance==null){
instance= new SingletonDemo2();
}
return instance;
}
}
双重检测锁
- 双重检测判断
- 使用volatile关键字,保证可见性
public class Singleton {
private volatile static Singleton sSingleton;
private Singleton() {
}
public static Singleton getSingleton() {
if (sSingleton == null) {
synchronized (Singleton.class) {
if (sSingleton == null) {
sSingleton = new Singleton();
}
}
}
return sSingleton;
}
}
静态内部类
- 外部类没有static关键字,所以不会立即加载
- 只有调用getInstance()时才会加载静态内部类,线程安全。instance前面加了static final关键字,因此保证了内存中只有这样一个实例存在,且只能赋值一次,final保证线程安全
- 具有并发高效调用和延迟加载的双重优点
public class SingletonDemo3 {
private static class SingletonClassInstance{
private static final SingletonDemo3 instance = new SingletonDemo3() ;
}
private SingletonDemo3(){
}
public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
}
}
枚举实现
- 实现简单
- 枚举本身就是单例模式
public enum SingletonDemo4 {
//枚举元素本身就是单例对象
INSTANCE;
//添加自己需要的操作
public void singletonOperation(){
}
}
如何防止反射和反序列化漏洞
- 反射可以破解上面几种(不包含枚举式)实现方式 --------------------------可以在构造方法中手动抛出异常控制
- 反序列化可以破解上面几种(不包含枚举式)实现方式
-------可以通过定义readResolve()防止获得不同对象。
--------反序列化时,如果对象所在类定义了readResolve(),定义返回哪个对象,实际是一种回调。
public class SingletonDemo5 {
//类初始化时,不初始化这个对象,(延时加载,真正用到的时候再创建)
private static SingletonDemo5 instance ;
private SingletonDemo5(){
if(instance !=null){
throw new RuntimeException();
}
}
//方法同步,效率低
public static synchronized SingletonDemo5 getInstance(){
if(instance==null){
instance= new SingletonDemo5();
}
return instance;
}
//反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不需要单独创建新的对象
private Object readResolve(){
return instance;
}
}
五种单例模式比较
单例对象占用资源少,不需要延时加载 -------枚举类好于饿汉式
单例对象占用资源大,需要延时加载 -------静态内部类好于懒汉式

设计模式之单例模式 Singleton实现的更多相关文章
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 设计模式(4) -- 单例模式(Singleton)
设计模式(4) -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...
- 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...
- 【设计模式】单例模式-Singleton
[设计模式]单例模式-SingletonEnsure a class has only one instance, and provide a global point to access of it ...
- 设计模式之——单例模式(Singleton)的常见应用场景
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...
- 设计模式之单例模式(Singleton Pattern)
单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...
- 设计模式一: 单例模式(Singleton)
简介 单例模式是属于创建型模式的一种(另外两种分别是结构型模式,行为型模式).是设计模式中最为简单的一种. 英文单词Singleton的数学含义是"有且仅有一个元素的集合". 从实 ...
- 设计模式之——单例模式(Singleton)的常见应用场景(转):
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...
- java设计模式之 单例模式 Singleton
static 的应用 单例模式 Singleton 单例:保证一个类在系统中最多只创建一个实例. 好处:由于过多创建对象实例,会产生过多的系统垃圾,需要GC频繁回收,由于GC会占用较大的系统资源,所有 ...
- 【设计模式】单例模式 Singleton Pattern
通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance) 的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...
随机推荐
- CoordinatorLayout使用笔记
CoordinatorLayout的使用笔记 首先第一个子控件是AppBarLayout存放首部控件,里面放了一个CollapsingToolbarLayout.代码如下: <android.s ...
- log4cxx安装使用
log4cxx安装使用 log4cxx现在是apache的一个项目,用来记录日志.看名字就知道,是给c++使用的. 环境(在以下2个环境中进行验证测试): gcc (Ubuntu 4.8.4-2ubu ...
- LibreOJ #2130. 「NOI2015」软件包管理器
内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名 树链剖分+线段树 屠龙宝刀点击就送 #include <vector> ...
- (转)在SQL Server 2016,Visual Studio 2017环境下,连接数据库屡屡失败,在connectionString上出的问题
适用情景: 1,ServerVersion出了问题,“SqlCnt.ServerVersion”引发了类型“System.InvalidOperationException”的异常 2,在String ...
- [opencv] applyColorMap
applyColorMap 功能 转化为热力图,因为热力图我们看的变化更加细微,在很多地方都用到了热力图. 最近在看CAM,所以记一记这个函数. 感觉还是很有用的. 代码 >>> i ...
- Mysql command line
show databasename; use databasename; show tables; desc tablename;
- vue入坑教程(二)在vue项目中如何导入element以及sass
在项目中导入element以及sass.stylus等方便开发的工具以及UI框架 (1)如何在vue项目中导入elementUI框架 elementUI是饿了么团队开发出来基于vue的前端UI框架,其 ...
- 安装 Win7 的系统的时候如何分区
解决方案 在安装Win7的系统的时候,可以使用下面方法进行分区: 1. 在出现同意许可条款,勾选“我接受许可条款(A)”后,点击下一步,然后继续下面操作: 2. 进入分区界面,点击“驱动器选项(高级) ...
- MySql下最好用的数据库管理工具是哪个
MySql下最好用的数据库管理工具是哪个? 维基上有个很全的列表: https://en.wikipedia.org/wiki/Comparison_of_database_tools 1. ph ...
- iOS重绘机制drawRect
iOS的绘图操作是在UIView类的drawRect方法中完成的,所以如果我们要想在一个UIView中绘图,需要写一个扩展UIView 的类,并重写drawRect方法,在这里进行绘图操作,程序会自动 ...