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.
它现在已经初始化了两次并且不是单例。
您有几个选项可以使其线程安全。
getInstance
方法同步 getInstance
可以直接返回它。 您也不需要使变量可变。在第 1 种情况下,无论如何同步该方法都会刷新变量,因此所有变量都将看到更新的副本。在第 2 种情况下,保证对象在构造后对所有对象可见。
关于java - java中具有不可变类的单例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15079161/