4

I'm attempting to port a Java application to Scala. One part of the Java application has an implementation called AtomicDoubleBuffer which uses an AtomicLongArray under the hood - using the result of Double.longBitsToDouble(value) to read from the double buffer and Double.doubleToRawLongBits(value) to write to the buffer.

I've been looking around the net for Scala implementation that could be better and I landed on this which says that this code block

class VolatileDoubleArray(val length : Int){
  val array = new Array[Double](length);
  @volatile var marker = 0;
  def apply(i : Int) = {marker; array(i); }
  def update(i : Int, x : Double) { array(i) = x; marker = 0; }
}

should give me happens-before guarantees. But I'm a little confused at how possible this is. Why should a volatile marker on one variable determine that a previous non-volatile "operation" succeeds? My interpretation of the JSL 17.4.5 suggests that updating elements of array in one thread does not guarantee that other threads will see that update. Am I missing something? Or am I confusing the whole happens-before thing?

Michael
  • 146
  • 1
  • 9

1 Answers1

1

This implementation in your example is correct, and makes the happen before guarantees.

Becuse write to volatile variable makes all things made before by the writing thread visible to all threads that first read this volatile variable.

The volatile "marker" variable is the point of memory barrier in this case.

in your example code: "

class VolatileDoubleArray(val length : Int){
  val array = new Array[Double](length);
  @volatile var marker = 0;
  def apply(i : Int) = {marker; array(i); }
  def update(i : Int, x : Double) { array(i) = x; marker = 0; }
}

"

when you write to the array in update you also write to volatile variable right after that using marker=0;, and before any read in apply from array you first read the volatile variable by just the statement marker;.

This makes any writes to the array (even performed by different threads) visible to any reads (happens before guarantee, in this case after any update is complete, any thread performing apply will see it).

Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
  • Hmm wasn't aware of that - any pointers would help. One question though, in that code snippet, isn't the compiler at any liberty of performing any optimisation given that `marker` is initialised with value `0` and is always set to the same value. I'm not sure but this looks like something the compiler could optimise out completely. Or is this illegal on a volatile variable? – Michael Oct 12 '16 at 13:03
  • 1
    No, compiler hasn't any liberty of performing any optimisation on volatile variables that could affect concurrent programming (like removing one, since the side-effect of read or write to volatile is making the memory barrier) nor the order of execution can be changed for them at runtime, that's exactly the purpose of volatile variables. – Krzysztof Cichocki Oct 13 '16 at 05:59
  • And for some pointers, I belive this is good reference: http://stackoverflow.com/questions/30246007/java-memory-model-volatile-variables-and-happens-before – Krzysztof Cichocki Oct 13 '16 at 07:45
  • Thanks, [here](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile) is another link that has cleared my confusion in addition to your help – Michael Oct 13 '16 at 09:12