- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章双重检查锁定模式Java中的陷阱案例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
双重检查锁定(也叫做双重检查锁定优化)是一种软件设计模式.
它的作用是减少延迟初始化在多线程环境下获取锁的次数,尤其是单例模式下比较突出.
- 软件设计模式:解决常用问题的通用解决方案。编程中针对一些常见业务固有的模版。
- 延迟初始化:在编程中,将对象的创建,值计算或其他昂贵过程延迟到第一次使用时进行。
- 单例模式:在一定范围内,只生成一个实例对象。
。
单例模式我们需保证实例只初始化一次.
下面例子在单线程环境奏效,多线程环境下会有线程安全问题(instance被初始化多次).
private static Singleton instance;public static Singleton getInstance() { if (null == instance) { instance = new Singleton(); } return instance;}
下面例子主要是性能问题。首先加锁操作开销很大,因为线程安全发生在对象初始化,而这里做了做了全局控制,造成浪费.
public synchronized static Singleton getInstance() { if (null == instance) { instance = new Singleton(); } return instance;}
为了控制线程安全又能保证性能,双重检查锁定模式出现.
public static Singleton getInstance() { if (null == instance) { synchronized (Singleton.class) { if (null == instance) { instance = new Singleton(); } } } return instance;}
逻辑如下:
我们分析一下执行逻辑:
假设有三个线程 T1 T2 T3 ,依次访问 getInstance 方法.
上面一切似乎很完美,但是这里面存在陷阱。根据Java内存模型我们知道,编译器优化处理会进行重排序.
instance = new Singleton() 大体分两个步骤; 。
而 1 2 步骤可能颠倒,会造成对象属性在初始化前调用的错误.
private static Singleton instance;...instance = new Singleton();...public class Singleton { private int age; public Singleton() { this.age = 80; }}
这种细微的错误不容易出现,但是它的确存在。大家可以参考下面这份报告,里面详细记录这个问题.
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 。
。
报告里面也列举了几种解决方案 。
private static final ThreadLocal<Singleton> threadInstance = new ThreadLocal<>();public static Singleton getInstance() { if (null == threadInstance.get()) { createInstance(); } return instance;}private static void createInstance() { synchronized (Singleton.class) { if (instance == null) instance = new Singleton(); } threadInstance.set(instance);}
private volatile static Singleton instance;public static Singleton getInstance() { if (null == instance) { synchronized (Singleton.class) { if (null == instance) { instance = new Singleton(); } } } return instance;}
下面是不同方案下的性能比较报告 。
http://www.cs.umd.edu/~pugh/java/memoryModel/DCL-performance.html 。
。
本章节主要记录了双重检查锁定模式使用中应该注意的细微事项.
请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.onlythinking.com/ 。
最后此篇关于双重检查锁定模式Java中的陷阱案例的文章就讲到这里了,如果你想了解更多关于双重检查锁定模式Java中的陷阱案例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
正如问题所说,C++ 程序员在转向 Java 时面临哪些常见/主要问题?我正在寻找一些广泛的主题名称或示例以及工程师必须进行的日常调整。然后我可以去深入阅读这个。 我对多年来使用 C++ 并不得不使用
我们正在准备发布一个在过去一年中一直在开发的大型网络应用程序。我们即将开始集成 ActiveMerchant 的过程,以处理该服务的经常性订阅费用。 我正在寻找关于考虑到我们的要求(如下所列)的最佳实
您陷入过哪些 Powershell 陷阱? :-) 我的是: # ----------------------------------- function foo() { @("text")
对于商业数据库而言,数据库升级是一个优先级很高的事情,有版本升级路线图,有相应的补丁,而且对于方案还有一系列的演练,显然是一场硬仗。而在MySQL方向上,升级这件事情就被淡化了许多,好像只能证明它的
Android 新增了 AsyncLayoutInflater类到他们的支持库版本 24.0 和更高版本,并且可以在 Android SDK 4.0 或更高版本(几乎所有可用的设备)中使用。 根据 A
作为一名刚接触 Vala 的程序员,您对刚接触该语言的人的第一条建议是什么? 最佳答案 这很大程度上取决于您的背景。如果您来自 C/C++/Java,最好的建议是学习函数式编程。 Vala 支持真正的
作为 Spring 世界的新手,我认为如果有一个社区 Wiki 页面列出基于 Spring 的项目中常见的陷阱会很好。 这些包括: 被误解的概念 在 Spring 3.X 中不再推荐的 Spring
我正在开发一个脚本来管理一些陷阱。一开始我只用这段代码管理 INT 和 SIGTSTP,它工作得很好: #!/bin/bash function capture_traps() { echo
bash 中是否可以在函数退出时调用某些命令。我的意思是: function foo { # something like this maybe? trap "echo \"exit
我们在我们的域中托管了一个应用程序。所有用户都需要先通过 POST 表单登录。登录后,表单会自动重定向到我们网站上的仪表板页面。 是否可以允许一些客户托管他们自己的登录表单(在他们的网站上),然后发布
我有一个无窗口计时器(没有 WM_TIMER),它只在给定的时间段过去后触发一次回调函数。它作为 SetTimer()/KillTimer() 实现。时间段足够小:100-300 毫秒。 对于每个如此
我使用 Java 大约一个月了,总体而言仍然是编程方面的业余爱好者,所以如果我有什么不对的地方,请随时纠正我。也许我会提供一些多余的细节,但我现在很困惑,无法决定什么才是重要的。 因此,我一直在开发多
我正在开发一个需要使用 FileSystemWatcher 类的 C# 程序,以便在创建新文件时通知它。作为初始化的一部分,程序会扫描目录,以便处理其中已存在的任何文件。一切正常。 但是,在与另一位开
下面材料整理自Internet&著作。 STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector 、deque);另一类是以不连续的节点形式存储的容器(如:list
我正在使用 NuGet 包 Polly实现捕获故障转移 SQL 异常的重试逻辑。我在 Azure 中设置了 SQL Server Always On 高可用性。 我不想捕获所有 SQL 异常(这是不正
在编写 Scala RemoteActor 代码时,我注意到了一些陷阱: 必须设置 RemoteActor.classLoader = getClass().getClassLoader() 以避免“
出于某种原因,当我针对不存在的文件运行以下脚本时,我的脚本没有捕获异常。我基于我在网上找到的示例中的代码,但它似乎对我不起作用。 我将不胜感激有关如何解决此问题的任何提示或指示。 注意:在下面的例子中
我正在尝试从 R 调用 winBUGS 来估计逻辑回归。我正在使用以下代码: # Directorio de trabajo setwd("~/3 Diplomado/7 Bayesiana/8t1"
我正在尝试从 R 调用 winBUGS 来估计逻辑回归。我正在使用以下代码: # Directorio de trabajo setwd("~/3 Diplomado/7 Bayesiana/8t1"
我正在使用 ctypes 包装一个大型 C 库。 ctypesgen生成了包装代码(与我自己的做法相差不远)。作为包装 C 结构的 ctypes 的一部分,它们被制作为对象,其中一些在 C 中具有“s
我是一名优秀的程序员,十分优秀!