【发布时间】:2012-11-20 19:45:13
【问题描述】:
我试图准确了解元素可见性如何在 java 中的数组上起作用。
给定班级:
class IntList {
private final int[] array;
public IntList(int[] array) {
this.array = array;
}
public int[] readElements() {
return Arrays.copyof(this.array, this.array.length);
}
}
以及以下用于创建实例的方法体:
int[] array = new int[length];
fillArrayWithRandomData(array); // puts data into the array from arbitrary source
return new IntList(array);
我想知道IntList 中的元素是否保证对获得对返回的IntList 的引用的其他线程可见?
我确信对数组的 REFERENCE 是可见的,因为它是最终的,但我似乎无法保证数组中的元素也可见。
注意:IntList 类没有允许修改数组的方法,并且数组引用不会发布到任何其他对象,我只是想知道构造后的可见性。
编辑:抱歉,在我的实际实现中,我的课程没有被称为 String。我把类名改成了IntList,因为好像太乱了。
编辑:
我要在这里给出的最终答案是肯定的,这些元素是可见的。
@MikeClark 找到了 JLS 的答案:
JLS § 17.5 “final 字段的使用模型很简单:在该对象的构造函数中设置对象的 final 字段;并且不要将对正在构造的对象的引用写在另一个线程可以在对象之前看到它的地方。构造函数完成。如果遵循这个,那么当另一个线程看到该对象时,该线程将始终看到该对象最终字段的正确构造版本。它还将看到那些最终字段引用的任何对象或数组的版本至少与最终字段一样最新。”
再次感谢!
【问题讨论】:
-
请不要将您的类称为内置类。字符串与 java.lang.String 冲突 - 可能会给您带来无穷无尽的问题。
-
@SamuelRossille “可见性”是讨论 [Java] 内存模型时经常使用的术语,这是一个与多线程高度相关的话题。例如,请参阅对 Java 内存模型的讨论,该讨论导致了修订后的 Java 5 JMM:ibm.com/developerworks/library/j-jtp03304。 “理解 JMM 所需的关键概念之一是可见性——你怎么知道如果线程 A 执行 someVariable = 3,其他线程会看到线程 A 写入的值 3?”
-
@TedHopp - 在提到跨线程所做的更改时,“可见性”一词也被大量使用。看这里:docs.oracle.com/javase/specs/jls/se5.0/html/memory.html
-
@MikeClark - 您应该将您的评论作为答案,因为当前的答案都没有完全正确。
-
@MikeClark 和 Brian 我不知道可见性的含义。无知导致了我的错误。发送信息。
标签: java arrays synchronization