单例模式

单例模式是指整个程序的运行中只有一个实例,并提供一个全局访问点。

单例模式模式的三个基本要点:

  • 这个类只能有一个实例;
  • 它必须自行创建这个实例;
  • 它必须自行向整个系统提供这个实例。

1. 饿汉方式

程序启动之后就会创建,但是创建完了之后可能不会使用,从而浪费了系统资源

优点:没有任何锁,执行效率高
适用于单例模式较少的场景:
如果我们在程序启动后,一定会加载到类,那么用饿汉模式实现的单例简单又实用;
如果我们是写一些工具类,则优先考虑使用懒汉模式,可以避免提前被加载到内存中,占用系统资源。

public class Singleton {// 1.创建私有的构造函数,为了防止其他类直接创建private Singleton(){}// 2.定义私有类变量(线程安全)private static Singleton singleton = new Singleton();// 3.提供公共的获取实例的方法public static Singleton getInstance() {return singleton;}
}

2. 懒汉模式

2.1 懒汉方式 (v1):

针对饿汉方式浪费资源的问题,将第二步

private static Singleton singleton = new Singleton()

修改为

private static Singleton singleton = null;

再在公共的获取实例的方法内进行判断,是否第一次访问,这样当程序启动之后并不会实例化,等什么时候调用什么时候才会初始化,防止资源的浪费

最后代码为:

public class Singleton {private Singleton(){}private static Singleton singleton = null;private static Singleton getInstance() {if(singleton == null) {singleton = new Singleton();}return singleton;}
}

这样解决了:
因为类加载时就初始化,浪费内存的问题,但是同样也带来的新的问题: 线程不安全

线程不安全的代码演示:

public class ThreadDemo {/*** 1.懒汉方式 V1(线程不安全)演示:*/static class Singleton {// 1.创建一个私有的构造函数private Singleton(){}// 2. 创建一个私有的类变量private static Singleton singleton = null;// 3. 提供统一的访问方法public static Singleton getInstance() throws InterruptedException {if (singleton == null) {Thread.sleep(1000);// 第一次访问singleton = new Singleton();}return singleton;}}private static Singleton s1 = null;private static Singleton s2 = null;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {try {s1 = Singleton.getInstance();} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {try {s2 = Singleton.getInstance();} catch (InterruptedException e) {e.printStackTrace();}}});t2.start();t1.join();t2.join();System.out.println(s1 == s2);}
}

运行结果可能为 false

线程 t1 t2
第一次访问 if (singleton == null) 括号内判断为 true
t2 获得时间片 还未实例化对象,t2 进入 if 判断也为 true

线程 t1 和 t2实例化了两个对象,线程不安全

2.2 懒汉方式 (v2):

给 getInstance() 方法加锁:

public class Singleton {private Singleton(){}private static Singleton singleton = null;// 给方法加锁private static synchronized Singleton getInstance() {if(singleton == null) {singleton = new Singleton();}return singleton;}
}

是解决了 v1 版本的第一次访问会出现线程不安全的问题
但是因为简单粗暴的给getInstance() 方法加锁,导致无论什么时候访问都要排队执行,大大降低了性能

2.3 懒汉方式 (v3):

使用双重校验

单例模式中饿汉模式和懒汉模式的线程安全问题相关推荐

  1. 单例模式(饿汉实现、懒汉实现)

    目录 (MS) 1. 饿汉实现 2.  懒汉模式 ① 单线程版本 ② 线程安全版 ③ 线程安全改进版⼀ 以上存在线程安全问题. ④ 线程安全改进版⼆ 以上存在线程安全问题,对象创建需要三步: ⑤ 线程 ...

  2. 【设计模式】之单例模式中的饿汉模式和懒汉模式

    本文内容:什么是单例模式,单例的作用,饿汉模式,懒汉模式的安全与非安全的实现,饿汉模式与懒汉模式的区别. 什么是单例模式? 单例模式:保证一个类,仅有一个实例.提供一个访问它的全局访问点. 单例的作用 ...

  3. 单例模式的四种实现方式(饿汉模式、懒汉模式、静态内部类、枚举类)

    首先,设计模式是我们程序员在软件开发过程中面临的一般问题的解决方案,通过学习设计模式可以使我们在编程时更加有条理性,同时培养我们写代码的思维能力,从而提高我们的工作效率.接下来就跟着博主的脚步往下走吧 ...

  4. 单例模式饿汉模式与懒汉模式

    目录 1.什么是单例模式 2.为什么需要单例模式? 3.如何实现单例模式 3.1饿汉方式 3.2懒汉模式 1.什么是单例模式 单例模式是一种设计模式,单例模式能保证某个类在程序中只存在唯一一份实例, ...

  5. 单例模式之饿汉、懒汉模式

    目录 1.单例模式 1.1 饿汉模式 1.2 懒汉模式 1.单例模式 单例模式能保证类在程序中只存在唯一一份实例.这一点在很多场景中都需要,比如JDBC中的DataSource实例就只需要一个. 单例 ...

  6. java设计模式之单例模式|单例模式之饿汉模式、懒汉模式、枚举方式|最详细的6种懒汉模式详解

    目录 一.单例模式 二.饿汉模式和懒汉模式 1.饿汉模式,线程安全 2.懒汉模式 懒汉模式1,线程不安全(不常用) 懒汉模式2,线程安全(不常用) 懒汉模式3,线程安全,双重校验(不常用) 懒汉模式4 ...

  7. 单例模式的具体实现(包含饿汉模式和懒汉模式)

    什么是单例模式? 确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 首先要建立这个实例: class Factory{public string Name { get; set; }p ...

  8. Java多线程案例——单例模式(恶汉模式和懒汉模式)

    一,什么是单例模式 单例顾名思义指的是单个实例对象(所以单例模式要求构造方法私有化才能保证在类外不能创建该类的实例化对象):在有的场景中,不应该创建多个对象时就应该使用单例模式,一旦使用了单例模式,此 ...

  9. 单例模式(饿汉单例模式and懒汉单例模式)

    文章目录 单例模式 单例模式是什么? 饿汉单例模式 饿汉单例是什么? 实现步骤 代码实现 懒汉单例模式 饿汉单例是什么? 实现步骤 代码实现 懒汉单例线程安全问题 解决方案 总结 单例模式 单例模式是 ...

  10. 单例模式之饿汉和懒汉(java)

    文章目录 1.前言 2.怎么区分饿汉和懒汉模式 3. 饿汉 4.懒汉 (双重检查 Double Check Lock) 5.饿汉模式在JDK中的应用(Runtime) 6.相关文章 1.前言 面试时, ...

最新文章

  1. 巧用CSS的BlendTrans滤镜
  2. Linux程序编译速度提高方法
  3. Spring Boot 打成war包部署到tomcat8.5.20报无法访问
  4. 第六周---事后分析
  5. 消息队列,我只选RabbitMQ!
  6. 转:python的内置对象
  7. ubuntu下使用vi是方向键变乱码 退格键不能使用的解决方法
  8. Linq 使用skip和take分页
  9. 量化策略回测唐安奇通道
  10. 学习IOS 开发需要什么?
  11. 如何知道域名是否解析成功
  12. LeetCode:每日一题(2020.4.6)
  13. visio 2010 激活方法
  14. 信息资源管理——基础
  15. php 开源留言系统,PHP开源多功能留言板(SyGuestBook)
  16. 激光雷达是什么?为什么移动机器人必不可少?
  17. 谈cntv.cn的启用
  18. ewebeditor
  19. 西宾知乎语音下载工具(zhihudownload)
  20. [转载]js技巧收集(200多个)

热门文章

  1. OCR开源代码库介绍
  2. 测度论与概率论基础(程士宏)学习笔记(一)
  3. Android中铃声总结源码
  4. java五子棋难度_简单五子棋JAVA
  5. MAC系统/虚拟机中的chm打不开
  6. 解读2022城市大脑首批三项标准
  7. win10系统ps3手柄蓝牙连接方法_ps3手柄怎么进入配对模式win10
  8. IE Tab Plus 安装设置说明
  9. CodeMeter***大赛战况:百人参赛,无人摘金!
  10. GNSS RTK 千寻位置 LG69T