Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 方法org.osgi.framework.Version.toString()是线程安全的吗?_Java_Multithreading_Thread Safety_Osgi - Fatal编程技术网

Java 方法org.osgi.framework.Version.toString()是线程安全的吗?

Java 方法org.osgi.framework.Version.toString()是线程安全的吗?,java,multithreading,thread-safety,osgi,Java,Multithreading,Thread Safety,Osgi,方法org.osgi.framework.Version.toString()已知会导致性能问题(请参阅)。为了解决这个问题,改变了方法,现在它利用了延迟初始化和数据竞争(可能是为了提高性能) 我认为这不是线程安全的,因为versionString字段的读取可以重新排序,并且该方法可以返回null值。我说得对吗?或者可能这并不重要,因为如果没有适当的同步,它永远不会被调用 更新 杰里米·曼森(Jeremy Manson)是JLS第17章并发性的作者之一,他在博客中写道,这种情况实际上是可能发生的

方法
org.osgi.framework.Version.toString()
已知会导致性能问题(请参阅)。为了解决这个问题,改变了方法,现在它利用了延迟初始化和数据竞争(可能是为了提高性能)

我认为这不是线程安全的,因为
versionString
字段的读取可以重新排序,并且该方法可以返回
null
值。我说得对吗?或者可能这并不重要,因为如果没有适当的同步,它永远不会被调用

更新


杰里米·曼森(Jeremy Manson)是JLS第17章并发性的作者之一,他在博客中写道,这种情况实际上是可能发生的。

与其说是懒惰,不如说是缓存

但您是对的,根据Java内存模型,它可以返回null

StringversionString;

public String toString() {
    if (versionString != null) {
        return versionString;  // can return null here!!
    }
理论上,它可以转化为

    String tmp1 = versionString;  // reads null
    String tmp2 = versionString;  // reads non-null
    if(tmp2!=null)
        return tmp1;              // return null!
然而,可能没有真正的JVM会这样做,所以这个bug可能永远不会实现

然而,“正确”的做法是

public String toString() {
    String tmp = versionString;
    if (tmp != null) {
        return tmp;
    }

不过最后一行还行

    return versionString = result.toString();
它不读取
versionString
,它相当于

    String tmp3 = result.toString();
    versionString = tmp3;
    return tmp3;
有趣的是,即使我们这样做了

    versionString = result.toString();   // [w]
    return versionString;                // [r]

它仍然安全。最后一次读取不能返回null,因为[w]发生在[r]之前。

我不确定是否同意。第一个if语句返回null的唯一方法是在if求值和执行返回之间另一个线程分配null,对吗?如所提供的示例所示,永远不会分配null(假设没有其他代码修改versionString),我是这段代码的作者。我可以通过杰里米·曼森(Jeremy Manson)的博客文章看出,这里有一个潜在的问题,尽管这个问题很小。我将更新此代码(以及R6的hashCode)以避免出现这种情况。谢谢
    versionString = result.toString();   // [w]
    return versionString;                // [r]