gpt4 book ai didi

java - java中具有不可变类的单例

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:49:56 25 4
gpt4 key购买 nike

class MyClass
{
private static volatile Resource resource;

public static Resource getInstance()
{
if(resource == null)
resource = new Resource();
return resource;
}
}

这里如果Resource是不可变类,写上面的代码安全吗?正如在实践中的 Java 并发性中提到的那样,“初始化安全允许正确构造的不可变对象(immutable对象)在线程之间安全地共享。所以上面的代码可以安全地编写。” (第 349 16.3 页)。但是有了这个,如果两个线程检查 null 并且它们可以继续创建对象,这可能会违反类的不变性(单例)。请解释。问题的延续 link

最佳答案

不,这不是线程安全代码。在这种情况下,Resource 可能是线程安全的,但您的 getInstance 方法不是。

想象一下这一系列事件

Thread1 calls getInstance and checks "if resource == null" and then stops (because the OS said it was time for it to be done) before initializing the resources.

Thread2 calls getInstance and checks "if resource == null" and then initializes the instance

Now Thread1 starts again and it also initializes the instance.

现在已经初始化了两次,不是单例。

您有几个选项可以使其成为线程安全的。

  1. 使 getInstance 方法同步

  2. 在声明时(或在静态初始化程序中)初始化实例,getInstance 可以直接返回它。

您也不需要使变量可变。在案例 #1 中,无论如何同步方法都会刷新变量,因此所有变量都将看到一个更新的副本。在情况 #2 中,对象保证在构造后对所有对象可见。

关于java - java中具有不可变类的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15079161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com