java - 单例中的双重检查锁定

标签 java multithreading design-patterns singleton

这是我的单例模式自定义类。在这段代码中,我使用了双重检查锁定,如下所示。当我在某些来源上阅读了许多帖子时,他们说双重检查很有用,因为它可以防止同时运行的两个并发线程生成两个不同的对象。

public class DoubleCheckLocking {

    public static class SearchBox {
        private static volatile SearchBox searchBox;

        // private constructor
        private SearchBox() {}

        // static method to get instance
        public static SearchBox getInstance() {
            if (searchBox == null) { // first time lock
                synchronized (SearchBox.class) {
                    if (searchBox == null) {  // second time lock
                        searchBox = new SearchBox();
                    }
                }
            }
            return searchBox;
        }
}

我还是不太明白上面的代码。实例为空时,如果两个线程一起运行同一行代码,有什么问题?

if (searchBox == null) {
                synchronized (SearchBox.class) {
                    if (searchBox == null) {
                        searchBox = new SearchBox();
                    }
                }
            }

当它出现时。两个线程都会看到对象为空。然后两者同步。然后,他们再次检查,仍然看到它为空。并创建两个不同的对象。哎呀。

请为我解释一下。我理解错了什么?

谢谢:)

最佳答案

不,由于您正在获取 SearchBox.class 的锁定,因此一次只有一个线程会进入同步块(synchronized block)。所以第一个线程进入然后发现 searchBox 为空并创建它然后离开同步块(synchronized block),然后第二个线程进入 block 然后它发现 searchBox 不为空因为第一个线程已经创建了它,所以它不会创建 searchBox 的新实例。

双重检查模式用于避免每次执行代码时都获得锁。如果调用没有一起发生,那么第一个条件将失败,代码执行将不会执行锁定,从而节省资源。

关于java - 单例中的双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18093735/

相关文章:

architecture - DTO DAO POCO BO

java - 无法在 TFS 位置构建 ant 目标

java - Spring Autowiring 对象在postcontruct方法中为空

Java-打破内部循环

c# - 中止使用 Delegate.BeginInvoke 启动的线程

android - Android 中的 fragment 和线程

Java - 用于重复 sql 任务的设计模式

java - 相同功能的两种变体的设计模式

java - 如何使用 Mockito 模拟 System.getProperty

c++ - 如何在Windows上正确打印处理线程?