Java EE 初阶---多线程二
目录
四、多线程案例之--单例模式
4.1 单例模式
是校招中最常考的设计模式之一.
啥是设计模式?
设计模式好比象棋中的 " 棋谱 ". 红方当头炮 , 黑方马来跳 . 针对红方的一些走法 , 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏 .软件开发中也有很多常见的 " 问题场景 ". 针对这些问题场景 , 大佬们总结出了一些固定的套路 . 按照这个套路来实现代码, 也不会吃亏 .
单例模式能保证某个类在程序中只存在唯一个一个地份实例, 而不会创建出多个实例.
这一点在很多场景上都需要. 比如 JDBC 中的 DataSource 实例就只需要一个.
(定义了数据库的用户名,密码,连接串,通过DataSource的实例对象获取数据库的连接)
单例模式具体的实现方式 , 分成 " 饿汉 " 和 " 懒汉 " 两种 .
4.2 怎么去设计一个单例?
1.口头约定
对外提供一个方法,要求大家使用这个对象的时候,通过这个方法来获取
(不靠谱,不采用)
2.使用编程语言本身的特性来处理
首先要分析清楚,在Java中哪些对象是全局唯一的
.class对象 比如String.class 类对象
饿汉模式
既然是单例那么通过new的方式去获取对象是有歧义的 那么就不能让外部去new这个对象
Singleton singleton = new Singleton();
-
//构造方法私有化
-
private Singleton(){}
-
public static Singleton getInstance(){
-
return instance;
-
}//用static修饰方法
-
-
private static Singleton instance = new Singleton();
-
//类似于这种类一加载就完成初始化的方式 称为饿汉模式
-
//书写简单不易出错
懒汉模式
避免程序启动的时候浪费过多的系统资源,当程序使用这个对象时再对它进行初始化
-
//定义一个类成员变量
-
private static SingletonLazy instance = null;
-
public static SingletonLazy getInstance(){
-
//在获取成员变量的时候判断是否已经初始创建
-
//如果没有则创建出来
-
if(instance == nul){
-
instance = new SingletonLazy();
-
}
-
return instance;
-
}
在多线程环境下获取单例对象:
-
// 创建多个线程,并获取单例对象
-
for (int i = 0; i < 10; i ) {
-
Thread thread = new Thread(() -> {
-
// 获取单例对象,并打印
-
SingletonLazy instance = SingletonLazy.getInstance();
-
System.out.println(instance);
-
});
-
// 启动线程
-
thread.start();
-
}
-
}
-
}
通过检查发现获取到了不同的对象,出现了线程不安全
分析造成线程不安全的原因:
为了解决这个问题,可以把初始化代码加锁:
public synchronized static SingletonLazy getInstance(){
可以看到依然出现了线程安全问题,那么就需要扩大锁的力度
输出正常、
但是还剩一个非常严重的问题!
举个栗子:
为了避免过度竞争消耗,加入一层判断
-
public static SingletonDCL getInstance() {
-
// 为了让后面的线程不再获取锁,避免了锁竞争造成的资源浪费
-
if (instance == null) {
-
synchronized (SingletonDCL.class) {
-
// 完成初始化操作,只执行一次
-
if (instance == null) {
-
instance = new SingletonDCL();
-
}
-
}
-
}
-
//双重检查锁
通过加synchnized关键字解决了原子性,内存可见性问题,那有序性如何保证?
那么就需要给共享变量加volatile关键字
-
public class SingletonDCL {
-
// 定义一个类成员变量
-
private volatile static SingletonDCL instance;
-
-
// 构造方法私有化
-
private SingletonDCL() {
-
}
-
-
public static SingletonDCL getInstance() {
-
// 为了让后面的线程不再获取锁,避免了锁竞争造成的资源浪费
-
if (instance == null) {
-
synchronized (SingletonDCL.class) {
-
// 完成初始化操作,只执行一次
-
if (instance == null) {
-
instance = new SingletonDCL();
-
}
-
}
-
}
-
// 返回实例对象
-
return instance;
-
}
-
}
4.3 两种模式的总结
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhigfich
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22 -
excel图片置于文字下方的方法
PHP中文网 06-27