The volatile key word and memory consistency errors

前端 未结 6 2003
借酒劲吻你
借酒劲吻你 2021-02-09 11:20

In the oracle Java documentation located here, the following is said:

Atomic actions cannot be interleaved, so they can be used without f

6条回答
  •  臣服心动
    2021-02-09 11:52

    The usual example:

    while(!condition)
        sleep(10);
    

    if condition is volatile, this behaves as expected. If it is not, the compiler is allowed to optimize this to

    if(!condition)
        for(;;)
            sleep(10);
    

    This is completely orthogonal to atomicity: if condition is of a hypothetical integer type that is not atomic, then the sequence

    thread 1 writes upper half to 0
    thread 2 reads upper half (0)
    thread 2 reads lower half (0)
    thread 1 writes lower half (1)
    

    can happen while the variable is updated from a nonzero value that just happens to have a lower half of zero to a nonzero value that has an upper half of zero; in this case, thread 2 reads the variable as zero. The volatile keyword in this case makes sure that thread 2 really reads the variable instead of using its local copy, but it does not affect timing.

    Third, atomicity does not protect against

    thread 1 reads value (0)
    thread 2 reads value (0)
    thread 1 writes incremented value (1)
    thread 2 writes incremented value (1)
    

    One of the best ways to use atomic volatile variables are the read and write counters of a ring buffer:

    thread 1 looks at read pointer, calculates free space
    thread 1 fills free space with data
    thread 1 updates write pointer (which is `volatile`, so the side effects of filling the free space are also committed before)
    thread 2 looks at write pointer, calculates amount of data received
    ...
    

    Here, no lock is needed to synchronize the threads, atomicity guarantees that the read and write pointers will always be accessed consistently and volatile enforces the necessary ordering.

提交回复
热议问题