Java - Immutable array thread-safety

后端 未结 4 1916
抹茶落季
抹茶落季 2021-02-08 13:30

I have a question regarding the Java Memory Model. Here is a simple class presenting the problem:

public class Immutable         


        
4条回答
  •  后悔当初
    2021-02-08 14:04

    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).

提交回复
热议问题