Deep understanding of volatile in Java

元气小坏坏 提交于 2019-12-05 20:28:24

Any actions before a volatile write happen before (HB) any subsequent volatile read of the same variable. In your case, the write to x happens before the write to g (due to program order).

So there are only three possibilities:

  • actor2 runs first and x and g are 0 - output is 0,0
  • actor1 runs first and x and g are 1 because of the happens before relationship HB - output is 1,1
  • the methods run concurrently and only x=1 is executed (not g=1) and the output could be either 0,1 or 0,0 (no volatile write so no guarantee)

No, this isn't possible. According to the JMM, anything that was visible to thread 1 when it writes to a volatile field becomes visible to thread 2 when it reads that field.

There is another example similar to yours provided here:

class VolatileExample {
  int x = 0;
  volatile boolean v = false;
  public void writer() {
    x = 42;
    v = true;
  }

  public void reader() {
    if (v == true) {
      //uses x - guaranteed to see 42.
    }
  }
}

No, and in fact this property of volatile is used in classes like ConcurrentHashMap to implement a lock-free happy path, roughly like this:

volatile int locked = 0;
...
void mutate() {
    if (Unsafe.compareAndSwapInt(locked,0,1)) { 
    /*this isn't exactly how you call this method, but the point stands: 
      if we read 0, we atomically replace it with 1 and continue on the happy 
      path */
       //we are happy
       //so we mutate the structure and then
       locked = 0;           
    } else {
       //contended lock, we aren't happy
    }
}

Since writes before a volatile write can't be reordered after the volatile write, and reads after volatile read can't be reordered before the volatile read, code like this indeed works as a "lockless locking".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!