JUC:double-checked locking(DCL) 懒汉单例模式

文章目录

  • double-checked locking(DCL) 问题
    • 解决方法
  • volatile作用

double-checked locking(DCL) 问题

  • 第一个if用于后续进入的线程,不用再获取锁来判断是否已经创建了对象。
  • 第二个if,为的是第一个进入的线程创建对象,以及防止卡在第一个if之后,获锁之前的线程在第一个线程已经创建对象的情况下,在获取锁后,判断不用创建对象,防止多次创建。

单例模式:

public final class Singleton {private Singleton() { }private static Singleton INSTANCE = null;public static Singleton getInstance() { if(INSTANCE == null) { // 首次访问同步,而之后的使用就不用 synchronized,所以在此行前加了判断  synchronized(Singleton.class) {if (INSTANCE == null) { INSTANCE = new Singleton(); } }}return INSTANCE;}
}

特点:

  • 懒汉式实例化
  • 首次使用加锁,之后不用加锁

但是,看似完美的代码,其实并不对,因为第一个if判断并不在synchronized中,所以可能会发生指令重排问题。

synchronized可以保证原子、有序、可见性,但是有序性需要变量完全synchronized被保护,这里第一个if并不在sync中,所以是可能发生下述情况的。

也就是说synchronized只能保证临界区内的指令不和临界区外的指令发生重排序。

比如先给INSTANCE赋值了,但是还没有调用构造方法,这时线程切换,他以为你创建好了对象,然后返回对象直接开始使用,是不是就出现问题了,因为我们对象还没构造呢。

在这里插入图片描述

解决方法

给Singleton加volatile。

public final class Singleton {private Singleton() { }private static volatile Singleton INSTANCE = null;public static Singleton getInstance() { if(INSTANCE == null) { // 首次访问同步,而之后的使用就不用 synchronized,所以在此行前加了判断  synchronized(Singleton.class) {if (INSTANCE == null) { INSTANCE = new Singleton(); } }}return INSTANCE;}
}

这样就是一个正确的代码了。

volatile作用

volatile作用:
可见性:

  • 写屏障(sfence)保证在该屏障之前对共享变量的改动,都同步到主存当中
  • 读屏障(lfence)保证在该屏障之后对共享变量的读取,加载的是主存中最新数据

有序性:

  • 写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
  • 读屏障会确保指令重排序时,不会将读屏障之后的代码排在读屏障之前

只能保证读数据正确,不能保证原子性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/787129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3.3优化了defineProps和defineEmits写法

针对defineProps的优化 父组件调用 <template><A :child"[yx]"></A> </template><script setup lang"ts">import A from ./A.vue</script>子组件 普通方法获取props 传递过来的之 <template><div>A c…

已解决MQClientException: No route info of this topic, mytopic异常的正确解决方法,亲测有效!!!

已解决MQClientException: No route info of this topic, mytopic异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 一、问题分析 二、报错原因 三、解决思路 四、解决方法 五、总结 博主v&#xff1a;XiaoMing_Java 一、问题分析 在使…

GEE:获取不同地表类型的Landsat地表温度(Land Surface Temperature,LST)时间序列

作者&#xff1a;CSDN _养乐多_ 本文将分享论文《Google Earth Engine Open-Source Code for Land Surface Temperature Estimation from the Landsat Series》中的基于Landsat时间序列影像计算地表温度的API和获取指定点&#xff08;Land Surface Temperature&#xff0c;LS…

题解 -- 第六届蓝桥杯大赛软件赛决赛C/C++ 大学 C 组

https://www.lanqiao.cn/paper/ 1 . 分机号 模拟就行 : inline void solve(){int n 0 ;for(int a1;a<9;a){for(int b0;b<9;b){for(int c0;c<9;c){if(a>b && b>c){n ;}}}}cout << n << endl ; } 2 . 五星填数 直接调用全排列的库函数…

ZCMU操作系统课程实验 - 实验1-Linux的使用

登录 1. 打开这个东西 2. 在 文件 - > 打开 中打卡机房里VMOS文件里的这个东东 3. 然后依次操作下去好了&#xff0c;有红色的选项&#xff0c;我都是选的"Do nothing"。完成后就会出现这样一个黑框框。 4. 让你登录。输入&#xff1a;root。密码&…

qt5.12版本源码交叉编译的错误

参考linux交叉编译Qt_linux qt 交叉编译-CSDN博客 配置阶段和编译阶段都有error 需要上按照上面的链接&#xff0c;进行修改源码&#xff0c;才能正常编译。 config配置 ./configure -prefix /home/c/qt-everywhere-src-5.12.1/aarch \ -opensource \ -release \ -confirm-l…

P6136 【模板】普通平衡树(数据加强版)题解 pb_ds 模版

【模板】普通平衡树&#xff08;数据加强版&#xff09; 传送门 题目背景 本题是 P3369 数据加强版&#xff0c;扩大数据范围并增加了强制在线。 题目的输入、输出和原题略有不同&#xff0c;但需要支持的操作相同。 题目描述 您需要写一种数据结构&#xff08;可参考题目…

提问的智慧-怎么提问

提问的智慧 转载自&#xff1a;Github&#xff08;https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md&#xff09;&#xff0c;没想到有中文版的&#xff0c;分享给你们。 How To Ask Questions The Smart Way Copyright © 2…

如何在Mac上停止旋转等待光标?这里提供详细步骤

序言 彩虹色的圆圈对于Mac用户来说是一个痛苦的景象。如果你幸运的话,它会在几秒钟内消失,但更常见的是,它会停留几分钟,让你无助地被锁在应用程序或整个Mac之外。 由于并不总是清楚如何处理转圈圈的光标,或者首先是什么导致了它,让我们将其分解。在本文中,我们将了解…

Google Hacking从0到1

文章目录 前言1、什么是google搜索1.1基础查询1.2高级搜索1.3使用布尔运算符 2、高级运算符2.1运算符语法2.2常用运算符 3、Google Hacking 基础3.1目录列出3.1.1 查找特定目录3.1.2 查找特定文件3.1.3 服务器版本 3.2目录遍历/目录穿越 4、10个简单的安全搜索5、总结参考 前言…

【C语言】InfiniBand内核驱动_mlx4_ib_post_send

一、注释 以下是_mlx4_ib_post_send函数的注释&#xff0c;该函数用于处理InfiniBand工作请求&#xff08;WRs&#xff09;的发送过程&#xff1a; static int _mlx4_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,const struct ib_send_wr **bad_wr, bool …

字符串处理之Manacher算法

字符串str中&#xff0c;最长回文子串的长度如何求解&#xff1f; //Manacher算法解决的问题 //字符串str中&#xff0c;最长回文子串的长度如何求解&#xff1f; //如何做到时间复杂度O(N)完成&#xff1f; public class Manacher {// //伪代码 // public static int[] manac…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(5)

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 初寒调色案例及练习图 等文件 https://www.alipan.…

记一次使用spring事件机制失效排查修复

前言 在日常业务开发中过程&#xff0c;我们有时候为了业务解耦&#xff0c;会利用spring的机制&#xff0c;就是利用spring提供的ApplicationListener、ApplicationEventMulticaster等核心API来实现。&#xff08;注&#xff1a; 我这边列的是核心底层API接口&#xff0c;正常…

shell脚本编写纪要

shell脚本后缀为.sh 1&#xff09;指定bash 首行&#xff0c;必须写下 #! /bin/bash 2) 修改可执行权限 chmod 777 xxx.sh 3)常用命令 echo "hello world"打印字符串 read xxxstr读取用户输入的字符串&#xff0c;回车结束&#xff0c;并将字符串赋值给变量xxxst…

常见故障排查和优化

一、MySQL单实例故障排查 故障现象 1 ERROR 2002 (HY000): Cant connect to local MySQL server through socket /data/mysql/mysql.sock (2) 问题分析&#xff1a;以上情况一般都是数据库未启动或者数据库端口被防火墙拦截导致。 解决方法&#xff1a;启动数据库或者防火墙…

电脑常见故障检测方法与对应问题分析说明

电脑常见故障检测方法与对应问题分析说明 前言说明1、机器无法开机故障2、屏幕无法显示3、无法联网4、能开机但是无法进入系统&#xff0c;提示not boot5、USB接口无法识别U盘 前言说明 本文为小白向&#xff0c;许多内容属于经验学而非科学&#xff0c;还望大佬们轻喷。 如上…

稠密连接网络(DenseNet)

文章目录 简介稠密连接&#xff1a; 简介 DenseNet的核心思想是改进网络中特征的传递方式&#xff0c;通过在每个层之间建立直接的连接&#xff08;即稠密连接&#xff09;&#xff0c;来提高信息流动和梯度传播的效率&#xff0c;从而解决深度神经网络中的梯度消失和梯度爆炸…

Word中使用Zotero插入文献

1. word 里面有插件 2. 插入文献 2.1 点击【Add/Edit Citation】 2.2 在方条中输入文献,回车 3. 显示Reference 在文档中选好reference的位置, 点击【Add/Edit Bibliograph

pygwalker+streamlit python看板库使用体验

算作前言 在 B 站看到 pygwalker 的介绍&#xff0c;很感兴趣。 是一个类似于简化版的 tableau 工具。 原版 docs PyGWalker 文档 – Kanaries 搭建看板 直接结合 streamlit 使用&#xff0c;streamlit 真的神器。 import pygwalker as pyg import pandas as pd import str…