目录:

  1、单例模式(Singleton Pattern)
  2、概念
  3、饿汉式:不是延迟加载,加载类的时候直接初始化
  4、懒汉式:延迟加载,首次需要使用的时候在实例化,需要考虑线程安全
  5、静态内部类实现
  6、枚举实现

1、单例模式(Singleton Pattern)   <==返回目录

    确保一个类只有一个实例,并提供一个全局访问点。

2、概念   <==返回目录

下面的内容转载自博客: 23种设计模式之单例模式 ( https://chenmingyu.top/design-singleton/)

  单例模式:单例模式属于创建型模式;

  定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。单例模式目的是保证在程序运行期间一个类只有一个实例,并提供一个全局访问点,无论什么情况下,只会生成一个实例,免去繁琐的创建销毁对象的过程。

  优点:

)减少了内存开支,避免频繁地创建、销毁对象;
)避免对资源的多重占用;

  缺点:

没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

  如何设计单例模式

    如何设计单例模式其实很简单,只需要考虑一个问题,实例是否可以保证是全局唯一。关于实例是否保证是全局唯一延伸出的问题:

是否线程安全,不安全肯定就不能保证全局只有一个实例
是否支持序列化,支持序列化的类,被反序列化之后肯定就不是全局唯一了
是否支持反射,支持反射肯定也不是全局唯一的
是否可以被克隆,这个也不能保证全局唯一

 

  所以设计一个安全的单例需要考虑的问题还是很多的。针对上述问题常见的解决办法:

保证线程安全,使用volatile+synchronized实现
防止序列化攻击,重写readResolve方法
防止反射,常用的方案是在单例类里增加一个boolean类型的flag标识,在实例化的时候先判断flag标识
防止克隆,重写clone()方法

  

  实现一个最简单的单例就需要考虑到以上的所有问题,这个时候什么有用的方法还没写那,代码就已经很多了,那有没有简单的办法既满足上述条件,代码又简洁那,那肯定有,使用枚举实现单例。

  常见的单例模式实现

常见的单例模式实现方案大概有五种,懒汉模式,饿汉模式,双重检查方式实现,静态内部类实现,枚举实现

  分个类:

是否支持延迟加载,分为懒汉模式和饿汉模式
线程安全设计了双重检查模式实现,静态内部类实现方式
不支持序列化,反射,克隆,枚举实现方式

  其中懒汉模式,饿汉模式,双重检查方式实现,静态内部类的实现方式都可以概括为以下两步:

  1.构造函数私有化,保证在外部无法new对象
  2.提供一个static方法获取当前实例(不同方案,实现不同)

  

  当然枚举的实现方式最简单,也最安全的,所以推荐使用枚举实现,其次推荐使用静态内部类方式实现。

3、饿汉式:不是延迟加载,加载类的时候直接初始化   <==返回目录

优点:线程安全,代码简单。

缺点:不是延迟加载,如果你用不到这个类,它也会实例化,还有一个问题就是如果这个实例依赖外部一些配置文件,参数什么的,在实例化之前就要获取到,否则就实例化异常

/**
* 单例模式:饿汉式
* @author oy
* @date 2019年9月3日 下午11:13:49
*/
public class Singleton { private static Singleton singleton = new Singleton(); private Singleton() {
} public static Singleton getInstance(){
return singleton;
}
}

4、懒汉式:延迟加载,首次需要使用的时候在实例化,需要考虑线程安全   <==返回目录

  线程不安全的实现方式:

/**
* 单例模式:懒汉式,线程不安全
* @author oy
* @date 2019年9月3日 下午11:15:47*/
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance(){
if(null == singleton){
singleton = new Singleton();
}
return singleton;
}
}

  线程安全的实现方式:双重检查(DCL:Double Check Lock)

/**
* 单例模式:双重检查(DCL:Double Check Lock)
* @author oy
* @date 2019年9月3日 下午11:17:06
*/
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {} public static Singleton getInstance(){
if(null == singleton){
synchronized (Singleton.class){
if(null == singleton){
singleton = new Singleton();
}
}
}
return singleton;
}
}

  面试题:为什么使用volatile修饰singleton变量?

1.说的volatile,首先肯定回答volatile的可见性
2.防止重排序优化,如果不用volatile修饰,多线程的情况下,可能会出现线程A进入synchronized代码块,
执行new Singleton();,首先给singleton分配内存,但是还没有初始化变量,
这时候线程B进入getInstance方法,进行第一个判断,此时singleton已经不为空,
直接返回singleton,然后肯定报错。使用volatile修饰之后禁止jvm重排序优化,所以就不会出现上面的问题

5、静态内部类实现   <==返回目录

  使用静态内部类实现也是延迟加载,利用静态内部类去实现线程安全,只有在第一次调用getInstance方法的时候才会去加载SingletonHolder,初始化SINGLETON

/**
* 单例模式:静态内部类实现
* @author oy
* @date 2019年9月3日 下午11:17:06
*/
public class Singleton { private Singleton() {} public static Singleton getInstance() {
return SingletonHolder.SINGLETON;
} private static class SingletonHolder {
private static final Singleton SINGLETON = new Singleton();
}
}

6、枚举实现   <==返回目录

  枚举实现代码更简洁,线程安全,并且保证枚举不会被反序列化,反射和克隆

/**
* 单例模式:枚举实现
* @author oy
* @date 2019年9月3日 下午11:17:06
*/
public enum Singleton { SINGLETON; /**
* 提供的方法
*/
public void method() {
System.out.println("枚举实现");
}
}

head first 设计模式笔记5-单例模式的更多相关文章

  1. php设计模式笔记:单例模式

    php设计模式笔记:单例模式 意图: 保证一个类仅有一个实例,并且提供一个全局访问点 单例模式有三个特点: 1.一个类只有一个实例2.它必须自行创建这个实例3.必须自行向整个系统提供这个实例 主要实现 ...

  2. Head First 设计模式笔记:单例模式

    单例模式 确保一个类只有一个实例,并提供一个全局访问点. 类图: Singleton static uniqueInstance //其他属性... static getInstance() //其他 ...

  3. IOS设计模式浅析之单例模式(Singleton)

    说在前面 进入正式的设计模式交流之前,扯点闲话.我们在项目开发的过程中,经常会不经意的使用一些常见的设计模式,如单例模式.工厂方法模式.观察者模式等,以前做.NET开发的时候,认真拜读了一下程杰老师的 ...

  4. 【白话设计模式四】单例模式(Singleton)

    转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...

  5. Java设计模式之《单例模式》及应用场景

    摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该 ...

  6. Java设计模式之【单例模式】

    Java设计模式之[单例模式] 何为单例 在应用的生存周期中,一个类的实例有且仅有一个 当在一些业务中需要规定某个类的实例有且仅有一个时,就可以用单例模式 比如spring容器默认初始化的实例就是单例 ...

  7. Java设计模式中的单例模式

    有时候在实际项目的开发中,我们会碰到这样一种情况,该类只允许存在一个实例化的对象,不允许存在一个以上的实例化对象,我们将这种情况称为Java设计模式中的单例模式.设计单例模式主要采用了Java的pri ...

  8. Java设计模式学习笔记(单例模式)

    最近一直在看<Head First设计模式>,这本书写的确实是很不错的,专注于怎么用最简单的方式最通俗的语言让人了解设计模式.据说GoF的设计模式那本书写的很好,是一本经典,但是就是难懂, ...

  9. Java设计模式学习笔记(五) 单例模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 使用单例模式的原因 以Windows任务管理器为例,在Windows系统中,任务管理器是唯 ...

  10. PHP 设计模式 笔记与总结(6)基础设计模式:工厂模式、单例模式和注册树模式

    三种基础设计模式(所有面向对象设计模式中最常见的三种): ① 工厂模式:使用工厂方法或者类生成对象,而不是在代码中直接new 在 Common 目录下新建 Factory.php: <?php ...

随机推荐

  1. pycharm2019最新激活注册码(亲测有效)

    激活码一: 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4MTJMRldNUlNIIiwibGljZW5zZWVOYW1lIjoi5q2j54mIIOaOiOadgyIsImFzc2l ...

  2. 查找担保圈-step2-拆分成员表函数

    USE [test] GO /****** Object: UserDefinedFunction [dbo].[tf_split_char] Script Date: 2019/7/8 14:39: ...

  3. <input> disabled 属性

    定义和用法 disabled 属性规定应该禁用输入字段. 被禁用的输入字段是无法使用和无法点击的. 如果使用该属性,则会禁用输入字段. 可以对 disabled 属性进行设置,使用户在满足某些条件时( ...

  4. ionic 提示 Error: Could not find gradle wrapper within Android SDK.

    Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK. 到And ...

  5. 18 Python之初识面向对象

    1. 类与对象 class Car: #类名首字母大写,严格遵守驼峰命名规范 pass #造车 c = Car() #类名() #创建对象 ##出场之后进行改装 c.color = "红色& ...

  6. js 发送异步请求

    js用XMLHttpRequest发送异步请求 发送GET请求 var xhr = new XMLHttpRequest(); xhr.open('GET',url);//url为请求地址 xhr.r ...

  7. vue-时间插件,效果见图

    <template> <div class="select-time-wrapper"> <h5 class="titie"> ...

  8. 第五篇 CSS入门 明白 三种嵌套形式,三种常用控制器

    CSS入门 css是 层叠式样式表   css的作用是什么呢?举个抽象的例子啊,HTML是人,CSS则是衣服...   css给html穿上衣服,有三种形式: 内嵌.内联.外联. 这三种形式,优先级为 ...

  9. springboot(1)-基础篇

    什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...

  10. 17、Nginx HTTPS 实践

    1.HTTPS安全证书基本概述 为什么需要使用HTTPS, 因为HTTP不安全.当我们使用http网站时,会遭到劫持和篡改,如果采用https协议,那么数据在传输过程中是加密的,所以黑客无法窃取或者篡 ...