-1

I'm currently running a separate task in a Java Swingworker, and here is the code (edited for clarity):

while (true) {
    while (value == 0) {
        value = utils.getValue();
        System.out.println("Value is zero");
    }
    System.out.println("Value isn't zero, out of loop");
}

This code runs perfectly fine. However, if I remove the println("Value is zero"), nothing happens, and the loop is never exited. Another thread is handling the population of the value, which gets updated roughly 5 seconds after the program starting.

I'm a little confused as to why the code only executes if there is a println in there. Can anyone shine any light on this?

Rahul
  • 44,383
  • 11
  • 84
  • 103
Tony
  • 3,587
  • 8
  • 44
  • 77
  • 2
    You never `break;` from the outer loop. – Maroun Jan 27 '14 at 13:01
  • 2
    We can't answer this question because we don't know what `getValue()` does. If `value` is always 0 you won't see any output but it'll still be running. – Jeroen Vannevel Jan 27 '14 at 13:01
  • getValue simply returns a value stored within another object. The value is zero to begin with, and after roughly 5 seconds of processing, the value is updated. – Tony Jan 27 '14 at 13:02
  • 2
    No relation with `println`. – Not a bug Jan 27 '14 at 13:02
  • @ᴍarounᴍaroun I think he refers to the inner loop and by nothing happens, he says that the outer loop doesn't print – diazazar Jan 27 '14 at 13:03
  • The outer loop does eventually break out, but I didn't include that extra code. Sorry about that. – Tony Jan 27 '14 at 13:03
  • What about a simple if (value != 0) run while else print message? – Marco Acierno Jan 27 '14 at 13:07
  • You say "Another thread is handling the population of the value". Maybe it's a concurrency/visibility issue? Would be nice if you could provide the whole code included in this operation. – u6f6o Jan 27 '14 at 13:14

2 Answers2

4
  • Long answer, read this.
  • Short answer, the value a thread stores in the heap may have been cached by other threads and if you don't synchronize them the resulting behavior may be surprising. It may be hard to know what happens and why. Access shared variables with synchronization or store shared values inside 'atomic' objects or 'volatile' variables.
aalku
  • 2,860
  • 2
  • 23
  • 44
-1

My best guess: add some sleep condition to give the other thread time to populate the result. In your question you say it takes about 5 seconds; this might take (way) longer when you add a busy-wait loop (while true).

try:

while (true) {
    while (value == 0) {
        value = utils.getValue();
        try {
            Thread.sleep(500);
        }
        catch (InterruptedException e) {
        }
        System.out.println("Value is zero");
    }
    System.out.println("Value isn't zero, out of loop");
}
R. Oosterholt
  • 7,720
  • 2
  • 53
  • 77
  • That's fixed it! Seems that it was something to do with the differing threads. Thanks for the solution! – Tony Jan 27 '14 at 13:10
  • You can also make the busy wait loop busier but working by using Thread.yield(); – LostBoy Jan 27 '14 at 14:47
  • 1
    Using `sleep` to fix thread issues is a terrible hack. – Kevin Panko Jan 27 '14 at 15:49
  • Sure it is. But taken the fact that a while loop is currently used, this solution fits. Rewriting the complete code to use events or wait for other threads would be better of course, but that seems a bit out of context here... – R. Oosterholt Jan 28 '14 at 11:20
  • No, this is not a solution but a hack. A **real** solution is to mark the `value` variable as `volatile`. An even better solution is to explain how threads and shared memory access work. – Luiggi Mendoza Aug 31 '14 at 17:33