Я не думаю, что приведенный выше фрагмент кода является поточно-ориентированным. Единственная строка, которая является безопасной для кода, это
aMap = new HashMap<String, String>();
В соответствии с примером, приведенным в http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html,
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // x is guaranteed to be 3
int j = f.y; // y can have any value
}
}
}
Это означает, что после инициализации последних полей безопасность потока не гарантируется. Поскольку только ссылочное присваивание гарантированно является потокобезопасным, а сам объект может быть изменяемым согласно вашему примеру. Следующее утверждение не может быть потокобезопасным
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
РЕДАКТИРОВАТЬ Мои плохие видели комментарии ниже кода позже
Приятно видеть правильно сконструированное значение для поля, но если само поле является ссылкой, то вы также хотите, чтобы ваш код видел обновленные значения для объекта (или массива), на который оно указывает , Если ваше поле является окончательным, это также гарантировано. Таким образом, вы можете иметь окончательный указатель на массив и не беспокоиться о том, что другие потоки видят правильные значения для ссылки на массив, но неправильные значения для содержимого массива. Опять же, под «правильным» здесь мы подразумеваем «обновленный на конец конструктора объекта», а не «последнее доступное значение».