0

I have a short while loop like:

boolean a = false;
MyClass b = new MyClass();
b.b = false;

// b is used in other thread...

while(!a){
   if(b.b){
      throw new Exception("b is true");
   }
}

In this case a will never became true, but after some runs the boolean variable b.b should became true. Strangely the while-loop was never left and my programm endet in an endless loop.

I woundered why and decided to add a System.out.print statement to the loop:

while(!a){
   if(b.b){
      throw new Exception("b is true");
   }
   System.out.println("there is something more to execute");
}

Remarkably my code works like it should be. The while loop runs over the if statement until b.b is true and the throwing of the exception leaves the loop.

Could it be that in the first case the program stops checking the if statement because the compiler thinks that it is not necessary to check again? If not, could anybody explain to me, why the first case does not work but the second one does?

team17
  • 796
  • 1
  • 8
  • 30
  • How do synchronize b.b between threads? – bowmore Apr 11 '17 at 17:07
  • 1
    why not use a break or set a to true when b.b is true inside your if? Throwing an exception for expected behavior isn't good design. – RAZ_Muh_Taz Apr 11 '17 at 17:09
  • 1
    Perhaps show us how b is being used in another thread – Chris Gong Apr 11 '17 at 17:11
  • Consider paying attention to your code. In the code you posted, b.b will never become true. That means infinite loop is the only possible outcome. – DwB Apr 11 '17 at 17:14
  • 1
    @DwB Consider paying attention to the code in the question. Notice the comment `// b is used in other thread...`. The other thread isn't shown in the question, but that doesn't mean it's not there, and it is not a far fetch to assume that it can change the value of `b.b`. – Andreas Apr 11 '17 at 17:23
  • Context of my code: the while loop waits for an API response: if there is a response i can easily set a = true, but if there is no respone i can just set the variable b of this class = false – team17 Apr 11 '17 at 17:26
  • @RAZ_Muh_Taz The Exception helps me to ignore the code directly after the while loop, notifies the user and prepares data for the next API request – team17 Apr 11 '17 at 17:33

1 Answers1

6

You need to mark your variables (whichever have got access to multiple threads) as volatile if you are working in a multithreaded environment, otherwise, it is not guaranteed for the current thread to see the results written by another thread.

In other words, one thread writes (changes) the value of your variable a and the other thread is not guaranteed to see it (because threads might copy/cache the variables), which is causing your while loop not to break.

I suggest you look here and understand how volatile works in a multithreaded environment. Below text (emphasis mine) taken from the same link:

Changes to a volatile variable are always visible to other threads. When a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

Vasu
  • 21,832
  • 11
  • 51
  • 67
  • Thanks for your answer. This kind of behavior was not known to me. Also described in http://stackoverflow.com/questions/25425130/loop-doesnt-see-changed-value-without-a-print-statement – team17 Apr 11 '17 at 17:23
  • no problem, `volatile' is a basic concept but an important one – Vasu Apr 11 '17 at 17:27