I have a question regarding the Java Memory Model. Here is a simple class presenting the problem:
public class Immutable
I think your array changes will be visible with your ImmutableIntArray. From my reading on JLS the [freeze] action should take place when constructor exits. The use of a temp array I think is useless:
int tmparray = new int[10];
for (int i = 0; i < 10; i++) {
tmparray[i] = i;
}
array = tmparray;
To obtain final field guaranties we will need a [freeze] somewhere before constructor exit:
int tmparray = new int[10];
for (int i = 0; i < 10; i++) {
tmparray[i] = i;
}
array = tmparray;
[freeze]
Anyway, [freeze] leaves the gates open to reorder instructions above it, so we will have the same thing:
int tmparray = new int[10];
array = tmparray;
for (int i = 0; i < 10; i++) {
tmparray[i] = i;
}
[freeze]
[freeze] is implemented to contain at minimum a [StoreStore]. This [StoreStore] barrier must be issued before the moment when instance constructed is published.
From JSR-133 Cookbook:
You cannot move stores of finals within constructors down below a store outside of the constructor that might make the object visible to other threads. (As seen below, this may also require issuing a barrier). Similarly, you cannot reorder either of the first two with the third assignment in: v.afield = 1; x.finalField = v; ... ; sharedRef = x;
And I think this is done by (JSR-133 Cookbook):
Issue a StoreStore barrier after all stores but before return from any constructor for any class with a final field.
So we can't store in sharedRef before all other contructor stores are done.
You can search by: "Transitive guarantees from final fields" in (JSR133 spec).