0

I am a beginner in concurrent programming, and i would like to understand exactly why this program doesn't end when I comment the sleep(1)in get() My first thought, is that the sleep(1) gives the hand back to the Mainthread, maybe Busy waiting has something to do with ?

public class Rdv<V> {
  private V value;

  public void set(V value) {
    Objects.requireNonNull(value);
    this.value = value;
  }

  public V get() throws InterruptedException {
    while(value == null) {
        Thread.sleep(1);  // then comment this line !
    }
    return value;
  }

  public static void main(String[] args) throws InterruptedException {
    Rdv<String> rendezVous = new Rdv<>();
    new Thread(() -> {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        throw new AssertionError(e);
      }
      rendezVous.set("hello");
    }).start();

    System.out.println(rendezVous.get());
  }
}
Iraponti
  • 95
  • 2
  • 3
  • 10
  • Related: https://stackoverflow.com/questions/42676751/thread-sleep-makes-compiler-read-value-every-time – shmosel Nov 19 '17 at 20:02

1 Answers1

2

First and foremost this program is seriously broken. There is no guarantee that it will terminate even with the sleep. It probably will, but it might not.

The problem is that the value field is not volatile and you don't use synchronized or other locks when you get/set the value. That means that there are no guarantees that one thread will see what another thread changes! The write to value that is supposed to stop the program may never be visible to the thread that is waiting. With the sleep in place, things normally work because Java is running in interpreted mode. Without the sleep the just in time compiler has had time to kick in and optimize the code. It sees that the while loop can be rewritten to a much more efficient version that does the same thing: loop forever. So that is what it does.

The easiest fix is to declare the value field as volatile. Then Java knows that it may change and avoids optimizing away the read.

Short version, unless you know the Java memory model well, always synchronize access to data shared between threads. Better safe than sorry!

ewramner
  • 5,810
  • 2
  • 17
  • 33
  • Thanks, of course this program is not safe at all, but it was just a weird exemple to understand what happen with the compiler and the VM – Iraponti Nov 19 '17 at 22:33