while(true){
if(longVariable < 2)
break;
}
In this code, there is no reason for the JVM to believe that longVariable
will ever change. It can effectively rewrite it to:
long cached = longVariable;
while(true){
if(cached < 2)
break;
}
Which loops infinitely if longVariable
is at least two when it executes, because nothing can change cached
.
You have to give the compiler a hint that this rewrite isn't allowed. It works with the System.out.println
on your JVM because it happens to be implemented with synchronization (which is common, but not required). This inserts memory barriers which means that the cached value of longVariable
is invalidated, and has to be read again.
But it's not guaranteed to work. To make it work correctly, either declare the variable volatile:
volatile long longVariable
which prevents its value from being cached.
Or use something like an AtomicLong
instead of a plain long
variable.
Or, most onerously, use explicit synchronization (ensuring that all reads of and writes to the variable are synchronized on the same "something"):
long v;
synchronized (something) {
v = longVariable;
}
if (v < 2) ...