Предоставляет ли следующий код безопасную публикацию?
public MyThread extends Thread {
@Override
public void run(){
for(int i=0; i < 100; i++){
MyObject[] array = new MyObject[16];
for(int j=0; j < 16; j++){
array[i] = new MyObject(j);
array[i].memberAttribute++;
}
// At this point the array is assigned to a shared volatile
// MyObject[] ref or put inside a concurrent collection
}
}
}
Happens-before здесь применяется к каждому вновь созданному объекту или только к самому массиву?
Даже если поле, которое будет удерживать j
внутри MyObject
, не является final
?
Да, это безопасная публикация, предполагающая, что вы также правильно прочитали ссылку на массив впоследствии (например, с помощью той же изменчивой переменной или под одной и той же блокировкой или из той же коллекции). Все записи в массив и в MyObject
в вашем коде происходят до того, как прочитать прочитанную ссылку, включая чтение элементов массива.
Counter-example: если вы опубликовали array
раннем этапе, скажем, сразу после new MyObject[16]
, то это происходит раньше, чем между записью в цикле и чтением опубликованной ссылки будет отсутствовать.