Я знаю, что конечные переменные экземпляра публикуются безопасно для всех потоков после завершения конструктора. Тем не менее, я задаюсь вопросом, является ли это еще безопасным, если конечная переменная-экземпляр содержит ссылку на объект, содержащий не конечную переменную-экземпляр. Эта вторичная, не конечная переменная-экземпляр никогда не изменяется после завершения конструктора. Рассмотрим следующий пример:Является ли безопасным публикация конечных переменных экземпляра транзитивным для не заключительных вторичных ссылок?
public class NonFinalImmutable {
private Iterable<String> list = Collections.unmodifiableList(Arrays
.asList("foo", "bar", "foobar"));
public Iterable<String> getList() {
return list;
}
}
public class FinalImmutable {
private final NonFinalImmutable reference;
private final String[] array;
public FinalImmutable(NonFinalImmutable reference,
String... arrayEntries) {
this.reference = reference;
this.array = arrayEntries;
}
public NonFinalImmutable getReference() {
return reference;
}
public String[] getArray() {
return array;
}
}
private void execute() {
new Thread() {
@Override
public void run() {
useLater(construct());
}
}.start();
}
private FinalImmutable construct() {
return new FinalImmutable(new NonFinalImmutable(), "asdf", "jklö");
}
private void useLater(FinalImmutable finalImmutable) {
new Thread() {
@Override
public void run() {
for (String s : finalImmutable.getReference().getList()) {
System.out.println(s);
}
System.out.println();
for (String s : finalImmutable.getArray()) {
System.out.println(s);
}
}
}.start();
}
Безопасно ли использовать содержимое экземпляра-переменных FinalImmutable.reference
и FinalImmutable.array
в другом потоке, даже если они содержат не конечный экземпляр-переменные?