Java双重检查锁定 [英] Java double checked locking

查看:118
本文介绍了Java双重检查锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发表了一篇文章,讨论了Java中的双重检查锁定模式及其缺陷,现在我想知道我多年来一直使用的那种模式的变体是否存在任何问题。

I happened upon an article recently discussing the double checked locking pattern in Java and its pitfalls and now I'm wondering if a variant of that pattern that I've been using for years now is subject to any issues.

我看了很多关于这个主题的帖子和文章,并了解了获取部分构造对象的引用的潜在问题,据我所知,我不知道t 认为我的实施受这些问题的影响。以下模式是否存在任何问题?

I've looked at many posts and articles on the subject and understand the potential issues with getting a reference to a partially constructed object, and as far as I can tell, I don't think my implementation is subject to these issues. Are there any issues with the following pattern?

如果没有,为什么人们不使用它?我在这个问题的任何讨论中都没有看过它。

And, if not, why don't people use it? I've never seen it recommended in any of the discussion I've seen around this issue.

public class Test {
    private static Test instance;
    private static boolean initialized = false;

    public static Test getInstance() {
        if (!initialized) {
            synchronized (Test.class) {
                if (!initialized) {
                    instance = new Test();
                    initialized = true;
                }
            }
        }
        return instance;
    }
}


推荐答案

< a href =http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html\"rel =noreferrer>双重检查锁定已损坏。由于initialized是一个原语,它可能不需要它是volatile来工作,但是没有什么能阻止初始化在初始化实例之前初始化被视为真正的非同步代码。

Double check locking is broken. Since initialized is a primitive, it may not require it to be volatile to work, however nothing prevents initialized being seen as true to the non-syncronized code before instance is initialized.

编辑:为了澄清上面的答案,原始问题询问使用布尔值来控制双重检查锁定。如果没有上述链接中的解决方案,它将无法正常工作。您可以仔细检查实际设置布尔值的锁定,但在创建类实例时仍然存在有关指令重新排序的问题。建议的解决方案不起作用,因为在非同步块中看到初始化的布尔值为true后,实例可能无法初始化。

To clarify the above answer, the original question asked about using a boolean to control the double check locking. Without the solutions in the link above, it will not work. You could double check lock actually setting a boolean, but you still have issues about instruction reordering when it comes to creating the class instance. The suggested solution does not work because instance may not be initialized after you see the initialized boolean as true in the non-syncronized block.

双重检查锁定的正确解决方案是要么使用volatile(在实例字段上)而忘记初始化的布尔值,并确保使用JDK 1.5或更高版本,或者在最终字段中对其进行初始化,如链接文章和Tom的回答中所述,或者只是不能使用它。

The proper solution to double-check locking is to either use volatile (on the instance field) and forget about the initialized boolean, and be sure to be using JDK 1.5 or greater, or initialize it in a final field, as elaborated in the linked article and Tom's answer, or just don't use it.

当然,整个概念似乎是一个巨大的过早优化,除非你知道你将获得大量关于获得这个Singleton的线程争用,或者你已经对该应用程序进行了描述,并将此视为热点。

Certainly the whole concept seems like a huge premature optimization unless you know you are going to get a ton of thread contention on getting this Singleton, or you have profiled the application and have seen this to be a hot spot.

这篇关于Java双重检查锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆