设计模式 单例模式解决线程安全问题
目录
一 实验
1.1 饿汉式多线程观察
1.2 懒汉式多线程观察
二 单例模式解决线程安全问题
2.1 Holder的方式解决单例模式线程安全问题
一 实验
首先我们看一下单例模式的饿汉式多线程和懒汉式多线程 getInstance()获取的实例是否是同一个
关于单例模式的基础使用请点这里
关于多线程实现的方式请看这里
现在开始
1.1 饿汉式多线程观察
package singletonMode;public class SingletonHungry {private static SingletonHungry singletonHungry = new SingletonHungry();private SingletonHungry(){System.out.println(this.getClass().getSimpleName()+"创建了");}public static SingletonHungry getInstance(){System.out.println("SingletonHungry getInstance");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return singletonHungry;}
}
package singletonMode;public class Client {public static void main(String[] args) {System.out.println("main线程:这是单例模式");//创建了一个线程,获取饿汉的实例new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程:"+SingletonHungry.getInstance());}}).start();System.out.println("main线程:"+SingletonHungry.getInstance());}
}
结果
1.2 懒汉式多线程观察
package singletonMode;public class SingletonLazy {private static SingletonLazy singletonLazy = null;private SingletonLazy(){System.out.println(this.getClass().getSimpleName()+"创建了");}public static SingletonLazy getInstance(){System.out.println("singletonLazy getInstance");if(singletonLazy == null){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}singletonLazy = new SingletonLazy();}return singletonLazy;}
}
package singletonMode;public class Client {public static void main(String[] args) {System.out.println("main线程:这是单例模式");//创建了一个线程,获取饿汉的实例new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程:"+SingletonLazy.getInstance());}}).start();System.out.println("main线程:"+SingletonLazy.getInstance());}
}
结果:
可以看到懒汉式多线程创建的实例并不是同一个,单例模式只能有一个实例,所以现在要解决这个问题
二 单例模式解决线程安全问题
我们可以用 同步方法/同步代码块来解决懒汉式的多线程安全问题,但始终会带来效率问题
下面我们用更好地方式来实现
2.1 Holder的方式解决单例模式线程安全问题
package singletonMode;/*** 最终极的单例模式的写法*/
public class SingletonHolder {private static class SingletonInnerHolder{private static SingletonHolder instance = new SingletonHolder();}private SingletonHolder(){System.out.println("SingletonHolder 构造函数");}public static SingletonHolder getInstance(){System.out.println("进入 SingletonHolder getInstance");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return SingletonInnerHolder.instance;}
}
测试类
package singletonMode;public class Client {public static void main(String[] args) {System.out.println("main线程:这是单例模式");//创建了一个线程,获取饿汉的实例new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程:"+SingletonHolder.getInstance());}}).start();System.out.println("main线程:"+SingletonHolder.getInstance());}
}
结果
ok了
总结:
饿汉式:线程安全,但是过早浪费资源 → 多个线程 getInstance()获取的实例是同一个
懒汉式:线程不安全,节约资源 → 不解决线程安全问题,多个线程 getInstance()获取的实例不是同一个
解决办法1:同步方法/同步代码块 → 始终会带来效率的问题
解决办法2:用Holder的方式创建一个内部类 → OK(单例模式 用这种好,推荐)
设计模式 单例模式解决线程安全问题相关推荐
- 单例模式及其线程安全问题
目录 1.设计模式 2.饿汉模式 3.懒汉模式 4.线程安全与单例模式 1.设计模式 设计模式是什么? 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案 这些解决方案是众多软件开发人 ...
- spring单例模式与线程安全问题的解决方案
一句话总结:1:spring容器创建对象的方式是单例的 2:spring单例模式的安全问题是使用ThreadLocal解决的 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行 ...
- 【解决线程安全问题:通过Lock锁对象】
[解决线程安全问题:通过Lock锁对象] 参考文章: (1)[解决线程安全问题:通过Lock锁对象] (2)https://www.cnblogs.com/zuixinxian/p/9570409.h ...
- 如何解决线程安全问题?有几种方式?synchronized与lock有什么异同?
1.谈谈你对同步代码块中同步监视器和共享数据的理解以及各自要求? 同步监视器:俗称锁.①任何一个类的对象都可以充当:②多个线程共用同一把锁. 共享数据:多个线程共同操作的数据. 2.什么情况会产生线程 ...
- 使用同步机制解决线程安全问题
线程的生命周期: 什么情况会产生线程安全问题? 当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,即产生线程安全问题.读的操作不会发生线程安全问题. 例子:上文中的卖票 ...
- java并发之如何解决线程安全问题
java并发之如何解决线程安全问题 参考文章: (1)java并发之如何解决线程安全问题 (2)https://www.cnblogs.com/w2154/p/6637717.html 备忘一下.
- 什么是线程安全问题 及怎么解决线程安全问题
1.什么是线程安全问题 就是 多线程环境中 , 且存在数据共享 , 一个线程访问的共享 数据被其他线程修改了, 那么就发生了线程安全问题 , 整个访问过程中 , 无一共享的数据被其他线程修改了 就是线 ...
- 如何解决线程安全问题
如何解决线程安全问题 怎么解决线程的安全问题呢? 基本上所有解决线程安全问题的方式都是采用"序列化临界资源访问"的方式,即在同一时刻只有一个线程操作临界资源,操作完了才能让其他线程 ...
- Java解决线程安全问题
文章目录 背景 1. 线程安全问题 1.1 什么是线程安全? 1.2 产生的原因 1.3 实例(买票超卖问题) 1.4 如何确定是否存在线程安全问题? 2. 如何解决线程安全问题? 2.1 不可变(I ...
- 4种解决线程安全问题的方式
前言 线程安全问题,在做高并发的系统的时候,是程序员经常需要考虑的地方.怎么有效的防止线程安全问题,保证数据的准确性?怎么合理的最大化的利用系统资源等,这些问题都需要充分的理解并运行线程.当然关于多线 ...
最新文章
- luoguP3387 【模板】缩点
- python语言入门n-python语言入门之字符串的一些用法
- vue--为什么data属性必须是一个函数
- python numpy矩阵的旋转, 转置, 正对角线镜像, 副对角线镜像, 行交换, 列交换操作 rot90()
- 全面 Severless 化只需要 7天!
- Exchange Server2010系列之七:多邮箱搜索找出神秘邮件的幕后黑手
- c++ 跳转到上级目录_Windows漏洞利用开发 第4部分:使用跳转定位Shellcode 模块
- CSS/DIV网页设计视频教程目录【转】
- 【壹个小技巧】一看就会的CI/CD :Github Actions
- 分析go程序内存逃逸情况
- SqlBulkCopy转载
- vivox6android版本5.1,vivo X6 Plus的手机系统是什么?能升级安卓5.0吗?
- c+mysql主从切换_mysql主从配置
- java发送邮件的两种实现方式(包括如何伪造发件人及其原理)
- cs61b实验记录(八)project 3:BearMaps 基于OSM的伯克利地图web应用
- 电脑一键装机软件哪个好 目前干净的一键重装系统软件推荐
- unity安装到一半失败
- 员工格言[付总提供]
- NR/5G - Timing Advance
- ESIM模拟器生成事件使用流程
热门文章
- 小米 android 7.0下载地址,小米5安卓7.0公测版固件下载地址 仅限开发版
- 以ASK调制解调为例观察采样与成型滤波的MATLAB仿真
- 斗鱼tv鸿蒙电视版,斗鱼直播鸿蒙版
- 扫雷外挂(扫雷辅助程序)
- linux编写的员工管理系统,员工信息管理系统设计与实现(叶晖).doc
- 显卡 真假测试软件,Gpuinfo beta6 显示卡信息检测工具,主要改进 NV 假卡识别
- sspanel 常用审计规则
- stringify中文乱码?
- 维修iphone6无服务器,苹果6通病——插卡无服务维修思路和教程
- python控制苹果手机触摸屏失灵怎么办_iPhone6触屏失灵,用一会就失灵,很恼火?...