multithreading - Why does an empty while in Java not break when condition is set by other thread? -
while trying unit test threaded class, decided use active waiting control behavior of tested class. using empty while statements failed intended. question is:
why first code not complete, second does?
there similar question, doesn't have real answer nor mcve , far more specific.
doesn't complete:
public class threadwhiletesting { private static boolean wait = true; private static final runnable runnable = () -> { try {thread.sleep(50);} catch (interruptedexception ignored) {} wait = false; }; public static void main(string[] args) { wait = true; new thread(runnable).start(); while (wait); // line important } }
does complete:
public class threadwhiletesting { private static boolean wait = true; private static final runnable runnable = () -> { try {thread.sleep(50);} catch (interruptedexception ignored) {} wait = false; }; public static void main(string[] args) { wait = true; new thread(runnable).start(); while (wait) { system.out.println(wait); // line important } } }
i suspect empty while gets optimized java compiler, not sure. if behavior intended, how can achieve want? (yes, active waiting intented since cannot use locks test.)
wait
isn't volatile , loop body empty, thread has no reason believe change. jit'd to
if (wait) while (true);
which never completes if wait
true.
the simple solution make wait
volatile
, prevents jit making optimization.
as why second version works: system.out.println
internally synchronized; described in jsr133 faq:
before can enter synchronized block, acquire monitor, has effect of invalidating local processor cache variables reloaded main memory.
so wait
variable re-read main memory next time around loop.
however, don't guarantee write of wait
variable in other thread committed main memory; so, @assylias notes above, might not work in conditions. (making variable volatile
fixes also).
Comments
Post a Comment