懒汉模式在多线程中的问题
由上一篇,了解到懒汉以及饿汉模式,目的是
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
但是,在多线程的情况下,会出现一些问题,如下代码,创建懒汉模式,但是通过同时 new 了两个线程来创建,此时两个线程一起走,但是创建需要延迟 2s 秒钟,所以创建的时候,判断 instance 都是 null,也就是说,两个线程创建了两个不同的对象,如图:
package demo11;/*** @Classname LazyMode* @Description 懒汉模式优化* @Date 2021/9/24 14:37* @Created by thx*/
public class LazyMode {public static void main(String[] args) {new Thread(() -> {TvStation tv = TvStation.getInstance();System.out.println(Thread.currentThread().getId() + " " + tv);}).start();new Thread(() -> {TvStation tv = TvStation.getInstance();System.out.println(Thread.currentThread().getId() + " " + tv);}).start();}
}class TvStation {/*** 懒汉模式*/private static TvStation instance = null;private TvStation() {System.out.println("开始创建超市,需要 2s ");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("创建结束");}public static TvStation getInstance() {if (instance == null) {instance = new TvStation();}return instance;}
}
那么如何解决这一问题呢?
使用 synchronized,然后再判断一次 空,此方法由于判断两次,所以叫 double-check
package demo11;/*** @Classname LazyMode* @Description 懒汉模式优化* @Date 2021/9/24 14:37* @Created by thx*/
public class LazyMode {public static void main(String[] args) {new Thread(() -> {TvStation tv = TvStation.getInstance();System.out.println(Thread.currentThread().getId() + " " + tv);}).start();new Thread(() -> {TvStation tv = TvStation.getInstance();System.out.println(Thread.currentThread().getId() + " " + tv);}).start();}
}class TvStation {/*** 懒汉模式*/private static TvStation instance = null;private TvStation() {System.out.println("开始创建超市,需要 2s ");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("创建结束");}public static TvStation getInstance() {// double-check 模式if (instance == null) {synchronized (TvStation.class) {if (instance == null) {instance = new TvStation();}}}return instance;}
}
此问题只在懒汉模式有效,饿汉模式没有这个问题。
枚举天生适应单例属性:
package demo11;import javax.swing.plaf.TableHeaderUI;/*** @Classname EnumMode* @Description* @Date 2021/9/24 14:56* @Created by thx*/
public class EnumMode {public static void main(String[] args) {RadioStation rs1 = RadioStation.CENTER;RadioStation rs2 = RadioStation.CENTER;System.out.println(rs1 + " " + rs2);new Thread(() -> {RadioStation rs3 = RadioStation.CENTER;}).start();new Thread(() -> {RadioStation rs4 = RadioStation.CENTER;}).start();}
}
enum RadioStation {CENTER;RadioStation() {System.out.println("开始创建电视台,需要 2s ");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("创建结束");}
}
懒汉模式在多线程中的问题相关推荐
- 单例模式之饿汉模式懒汉模式
前言 单例模式能保证某个类在程序中只存在唯一一份实例,而不会创建出多个实例,比如 JDBC 中的 DataSource 实例就只需要一个.单例模式具体的实现方式有"饿汉" 和 &q ...
- Java多线程案例——单例模式(恶汉模式和懒汉模式)
一,什么是单例模式 单例顾名思义指的是单个实例对象(所以单例模式要求构造方法私有化才能保证在类外不能创建该类的实例化对象):在有的场景中,不应该创建多个对象时就应该使用单例模式,一旦使用了单例模式,此 ...
- 23种设计模式C++源码与UML实现--单例模式中的饿汉模式和懒汉模式
单例模式 单例模式是一种对象创建模式,使用单例模式,可以保证为一个类生成唯一的实例对象.也就是说在这个程序空间该类只有一个实例对象. GoF对单例的定义:保证一个类.只有一个实例存在,同时提供对该实例 ...
- DCL实现多线程安全的高性能懒汉模式
DCL实现多线程安全的高性能懒汉模式 1.单线程安全的懒汉模式实现 源码: private static LazyLoad instance = null;public static LazyLoad ...
- Scala中简单实现懒汉模式和饿汉模式
在Scala中简单实现单例模式,代码如下: object Test_Singleton {def main(args: Array[String]): Unit = {// 测试是否成功// 懒汉va ...
- 学习多线程中的 Future 模式一篇文章就够了 !!!
文章目录 一.Future 模式 二.Future模式的主要角色 三.Future模式的简单实现 四.JDK中的Future模式 五.Guava对Future模式的支持 一.Future 模式 Fut ...
- 【设计模式】之单例模式中的饿汉模式和懒汉模式
本文内容:什么是单例模式,单例的作用,饿汉模式,懒汉模式的安全与非安全的实现,饿汉模式与懒汉模式的区别. 什么是单例模式? 单例模式:保证一个类,仅有一个实例.提供一个访问它的全局访问点. 单例的作用 ...
- 单例模式 之 单例模式——懒汉模式
懒汉模式:和饿汉模式不同,懒汉模式并不会一开始声明对象,而是需要等到调用时再声明对象.他很懒,所以你叫"它"它才会动... 代码1: /*** 懒汉模式*/ public clas ...
- 单例模式---懒汉模式与饿汉模式
单例模式:1)一个类只能创建一个实例2)构造函数和静态变量(加载类时即初始化)需为private3)get方法应该为public static,可供全局访问 //懒汉模式 public class l ...
最新文章
- MFC单文档框架编程(一): 分隔窗口的实现
- 命令行启动Angular应用
- java发送文件_java 模拟http发送文件和参数
- linux 安装redis_Linux安装redis及安装php-redis扩展
- 5.1特辑 | 为什么显示有票你却抢不到?技术揭秘12306如何保证车票不超卖
- Python文件操作与函数目录
- 拼包函数及网络封包的异常处理
- N天学习一个Linux命令之grep
- Java项目:药品管理系统(java+SSM+html+jQuery+Tomcat+mysql)
- C# WinForm程序中使用Unity3D控件
- 微信小程序云开发--数据库使用
- 网口扫盲三:以太网芯片MAC和PHY的关系
- 计算机应用期刊查重率要求,计算机学报先审稿还是先查重
- 修改IAR for msp430工程名方法
- 蓝本(blueprint)
- win10安装java环境15版_win10系统安装jdk的配置方法
- js日期格式转换Wed Mar 22 13:38:37 CST 2017 转换 为yyyy-mm-dd
- 大牛养成指南(2):先实现一个小目标吧!10000小时理论如何轻松落地
- 解开硬盘逻辑死锁的一种有效方法 (转)
- 在校外,如何免费下载知网上的文献论文的方法