Does volatile influence non-volatile variables?

前端 未结 4 1819
盖世英雄少女心
盖世英雄少女心 2021-02-20 14:11

Okay, suppose I have a bunch of variables, one of them declared volatile:

int a;
int b;
int c;
volatile int v;

If one thread writes to all four

4条回答
  •  粉色の甜心
    2021-02-20 14:48

    I'm going to speak to what I think you may really be probing about—piggybacking synchronization.

    The technique that it looks like you're trying to use involves using one volatile variable as a synchronization guard in concert with one or more other non-volatile variables. This technique is applicable when the following conditions hold true:

    • Only one thread will write to the set of values meant to be guarded.
    • The threads reading the set of values will read them only if the volatile guard value meets some criteria.

    You don't mention the second condition holding true for your example, but we can examine it anyway. The model for the writer is as follows:

    • Write to all the non-volatile variables, assuming that no other thread will try to read them.
    • Once complete, write a value to the volatile guard variable that indicates that the readers' criteria is met.

    The readers operate as follows:

    • Read the volatile guard variable at any time, and if its value meets the criteria, then
    • Read the other non-volatile variables.

    The readers must not read the other non-volatile variables if the volatile guard variable does not yet indicate a proper value.

    The guard variable is acting as a gate. It's closed until the writer sets it to a particular value, or set of values that all meet the criteria of indicating that the gate is now open. The non-volatile variables are guarded behind the gate. The reader is not permitted to read them until the gate opens. Once the gate is open, the reader will see a consistent view of the set of non-volatile variables.

    Note that it is not safe to run this protocol repeatedly. The writer can't keep changing the non-volatile variables once it's opened the gate. At that point, multiple reader threads may be reading those other variables, and they can—though are not guaranteed—see updates to those variables. Seeing some but not all of those updates would yield inconsistent views of the set.

    Backing up, the trick here is to control access to a set of variables without either

    • creating a structure to hold them all, to which an atomic reference could be swapped, um, atomically, or
    • using a lock to make writing to and reading from the entire set of variables mutually exclusive activities.

    Piggybacking on top of the volatile guard variable is a clever stunt—not one to be done casually. Subsequent updates to the program can break the aforementioned fragile conditions, removing the consistency guarantees afforded by the Java memory model. Should you choose to use this technique, document its invariants and requirements in the code clearly.

提交回复
热议问题