只是为了确保。 我在实践书中遵循Java Concurrency。 当谈到安全发布时尤其是最终版本,我很清楚,首先引用将对所有其他线程可见,其次发布对象的状态对于任何其他线程是可见的,但这里的问题是如果状态是引用的数组元素保证在发布状态时可见? (当然,只要没有人修改这些数据对象)。
示例:
@Mutable
public class NotThreadsafeDataObject {
private String message;
public NotThreadsafeDataObject (String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
现在让我们安全地发布一系列可变对象:
public class Publish {
public final NotThreadsafeDataObject[] publish;
public Publish() {
publish = new NotThreadsafeDataObject[] { new NotThreadsafeDataObject("one"), new NotThreadsafeDataObject("two")};
}
}
答案 0 :(得分:0)
如果我们用“Java Concurrency in Practice”中提到的术语来说话,那么你的数组就是一个“有效不可变”的对象。对于此类对象,始终需要安全发布,以免破坏内部状态。所以你的代码没问题,因为你正在使用安全的发布。更具体地说,“final”关键字内存语义保证访问final字段的线程将看到在字段写入之前发生的所有事情(“之前发生”)。
答案 1 :(得分:0)
我很确定您仍然可以修改Array中各个可变对象的值。即
publish[0].setMessaage("Hello");
会工作得很好。而且我相信你可以从数组中删除对象。它是不能更改的Array引用,因为它被声明为final
。如果你想拥有完全不可变的集合,我会使用声明为final的List,然后创建一个新的单独List,填充它然后使用方法public static List unmodifiableList(List list)将它分配到你的最终列表:
ublic class Publish {
public static final List<NotThreadsafeDataObject> publish;
static {
init();
}
private static void synchronized init() {
List<NotThreadsafeDataObject> list = new ArrayList<>();
list.add(new NotThreadsafeDataObject("one");
list.add(new NotThreadsafeDataObject("two");
publish = Collections.unmodifiableList(list);
}
}
这使得防弹完全不可变的列表既不能改变它也不能改变它的内容。