多线程情况下双重检查锁定问题的分析与优化
程序员文章站
2022-03-25 12:02:38
...
双重检查锁定(Double-Checked Locking)的由来
Java程序中,有时候需要推迟一些高开销对象的初始化操作,等到使用的时候才进行对象初始化。双重检查锁定是一种常见的延迟初始化技术。但是在多线程情况下,使用不当很容易出现问题。下面就来分析一下非线程安全的一段代码:
从代码来看,如果第一次检查instance不为null,则不用继续执行加锁和初始化操作,可以降低synchronized带来的性能开销。但是如果在多线程情况下一个线程 执行第一次检查的时读取的instance不为null,然而此时instance引用的对象在另外一个线程中还没有初始化完成,这时程序就会出现错误。
参考:https://blog.csdn.net/u012739535/article/details/76039983
https://blog.csdn.net/qq_27489007/article/details/84966680
Java程序中,有时候需要推迟一些高开销对象的初始化操作,等到使用的时候才进行对象初始化。双重检查锁定是一种常见的延迟初始化技术。但是在多线程情况下,使用不当很容易出现问题。下面就来分析一下非线程安全的一段代码:
public class DoubleCheckedLocking { private static Instance instance; public static Instance getInstance() { if (instance == null) { // line A 第一次检查 synchronized (DoubleCheckedLocking.class) { // line B 加锁 if (instance == null) { // line C 第二次检查 instance = new Instance(); // line D 创建一个对象。 问题就出在这里!!! } } } return instance; } }
从代码来看,如果第一次检查instance不为null,则不用继续执行加锁和初始化操作,可以降低synchronized带来的性能开销。但是如果在多线程情况下一个线程 执行第一次检查的时读取的instance不为null,然而此时instance引用的对象在另外一个线程中还没有初始化完成,这时程序就会出现错误。
参考:https://blog.csdn.net/u012739535/article/details/76039983
https://blog.csdn.net/qq_27489007/article/details/84966680