Does a correctly synchronized program still allow data race?(Part I)

后端 未结 3 550
栀梦
栀梦 2020-12-10 17:54

There are two conclusions from JLS:

  • C1: If a program is free of data races, then all executions of the program will appear to be sequentially consistent:
3条回答
  •  清歌不尽
    2020-12-10 18:51

    A good example could be String's hashcode:

    private int hash; // Default to 0
    
    public int hashCode() {
        int h = hash;
        if (h == 0 && count > 0) {
            int off = offset;
            char val[] = value;
            int len = count;
    
            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }
    

    There is a data race here as hash can be written and read by different threads and there is no happens-before relationship (no synchronization).

    However the program is sequentially consistent because it is impossible for a thread to see a hashcode which is not the actual hashcode of the string (when a thread executes the hashcode method, it can either see 0 and recalculate the value, which is deterministic, or it sees a valid value). This works because int writes are atomic.

    EDIT

    This (almost) same code is broken and could return a hashcode of 0:

    public int hashCode() {
        if (hash == 0 && count > 0) { //(1)
            int h = hash;
            int off = offset;
            char val[] = value;
            int len = count;
    
            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return hash; //(2)
    }
    

    as (1) and (2) could be reordered: (1) could read a non null value while (2) would read 0. That can't happen in the first example because the calculation is made on the local variable and the return value is also that local variable, which, by definition, is thread safe.

    EDIT 2

    Regarding your proposition C4, I don't think it is possible:

    A program is correctly synchronized if and only if all sequentially consistent executions are free of data races.

    If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent (§17.4.3).

    So if a program is correctly synchronized:

    • all the executions appear sequentially consistent.
    • all sequentially consistent executions are free of data races

    So we can conclude that all executions are free of data races and therefore the program is free of data races.

提交回复
热议问题