一篇讲双锁检测的文章

2024-03-18 00:18
文章标签 检测 文章 一篇 双锁

本文主要是介绍一篇讲双锁检测的文章,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题来源于群里面一个同学发了一篇关于双锁检测的文章,然后就有人反对说,双锁检测是过时的。于是乎,我也去找了一下相关的文章。http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html,这一篇文,就是发到群里面的文章。

虽然这篇文章说了在1.5之后,可以使用final字段让对象完全初始化。但是,并没有说明,如果我们使用普通的成员变量,会不会造成对象半初始化对象。这里有一个共同的前提,就是这个被初始化对象是volatile类型。当时本人就给定了一个结论说如果被初始化对象包含普通类型字段(非final和volatile),那么,双锁检测一定是失败的,造成未完全初始化的对象。所以当时这个结论就错了,参考这篇文章http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html对新java内存模型的解读


Under the old memory model, accesses to volatile variables could not be reordered with each other, but they could be reordered with nonvolatile variable accesses. This undermined the usefulness of volatile fields as a means of signaling conditions from one thread to another.

这句话说明,在老的内存模型中,volatile是不能阻止对非volatile变量操作的重排序,从而volatile变量不能作为一种用于线程间通信的信号条件(这尼玛,怎么翻译,看代码就理解了)。

Under the new memory model, it is still true that volatile variables cannot be reordered with each other. The difference is that it is now no longer so easy to reorder normal field accesses around them. Writing to a volatile field has the same memory effect as a monitor release, and reading from a volatile field has the same memory effect as a monitor acquire. In effect, because the new memory model places stricter constraints on reordering of volatile field accesses with other field accesses, volatile or not, anything that was visible to thread A when it writes to volatile field f becomes visible to thread B when it reads f.

然后,这句话就说了,volatile对其他的非volatile变量也有可见性保证,于是,当使用volatile的时候,用于线程间的通信的信号条件,我们可以安全的使用双锁检测了。具体能够搜索的相关资料包括:jsr133(happen before,重排序,可见性)。
 

故事永远不是这么简单的结束的,结束实际上来源于两段诡异的代码。大致意思是,一个线程不断的创建ArrayList赋值给一个全局变量,另外几个线程同时读取这个ArrayList并调用add方法,那么在-server的jit编译下,会导致nullPointexception,如果对这个全局数组加上volatile,那么就不会抛这个异常出来(参考代码片段2)。

  另外一段代码就是模拟,工作线程copy 主内存的Integer,然后另一个线程不断给Integer赋值null,同样不会报错。这里有个技巧||和&&的区别。(参考代码片段1)


这里插上两段代码--

1.不会报错,因为max被copy到工作线程,当max加上volatile时,可以看到直接出错,因为max为null

public class Main {public static Integer max = null;public static void main(String[] args){Thread[] threads = new Thread[20];for (int i = 0; i < threads.length; i++) {threads[i] = new Thread(new Runnable() {@Overridepublic void run() {while (true) {if(max == null || max > 10){max = 10;}}}});threads[i].start();}Thread t1 = new Thread(){public void run(){while(true){max = null;}}};t1.start();}
}

2,这段代码会报错,因为重排序问题,导致l变量半初始化,ArrayList中的elementData并未成功初始化,调用l.size()时,发生NP错误。如果我们加上volatile修饰l,那么便不会报错了
</pre><span style="background-color: rgb(0, 0, 0);"></span><pre name="code" class="java">public class Test {public static List<String> l = new ArrayList<String>(1024); public static void main(String[] args) {
Thread[] threads = new Thread[20];for (int i = 0; i < threads.length; i++) {threads[i] = new Thread(new Runnable() {@Overridepublic void run() {int j = 0;while (true) {synchronized (HmacSHA1.class) {if(l.size() < 1024)l.add("ttt");}}}});threads[i].start();}Thread t1 = new Thread(){public void run(){while(true){List<String> local = l;l = new ArrayList<String>(1024);}}};t1.start();}}



这篇关于一篇讲双锁检测的文章的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/820646

相关文章

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

C#自动化实现检测并删除PDF文件中的空白页面

《C#自动化实现检测并删除PDF文件中的空白页面》PDF文档在日常工作和生活中扮演着重要的角色,本文将深入探讨如何使用C#编程语言,结合强大的PDF处理库,自动化地检测并删除PDF文件中的空白页面,感... 目录理解PDF空白页的定义与挑战引入Spire.PDF for .NET库核心实现:检测并删除空白页

Python脚本轻松实现检测麦克风功能

《Python脚本轻松实现检测麦克风功能》在进行音频处理或开发需要使用麦克风的应用程序时,确保麦克风功能正常是非常重要的,本文将介绍一个简单的Python脚本,能够帮助我们检测本地麦克风的功能,需要的... 目录轻松检测麦克风功能脚本介绍一、python环境准备二、代码解析三、使用方法四、知识扩展轻松检测麦

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形