Why do thread behave different with different run method body?
java, multithreading, synchronization, volatile
Solution
Precisely, it is just not guaranteed that the thread will ever stop, but it is not forbidden that it does stop. The logic behind this is provided by the Java Memory Model, which is a rather complicated topic, but needed in order to understand Multithreading in Java.
The concept is that a write to a non-volatile field of one thread is only required to be seen by another thread if these two actions synchronize with each other. A compiler is allow to reorder some actions if the behavior exhibited by the thread it is executed in does not change. But another thread might see this. So you need proper synchronization in order to tell the compiler that reordering is not allowed in some parts.
Read the full paper about this here: JSR-133
Problem
This code is from Effective Java (Item 66): (without sync or volatile this never ends) ``` public class ThreadPractice { static boolean canrunstatic; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!canrunstatic){i++;} System.out.println("finished"); } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); canrunstatic = true; } ``` As Bloch mentioned in that chapter it will never write "finished" to the console. I've been playing around with this class, and add that line to the runnable run method: ``` System.out.println("im still running"); ``` With this the while loop doesn't only increment i but prints out this string in every loop. But what drives me crazy, that this way the thread stops after 1 sec, when main thread comes back from sleep. modified: (stops without volatile/sync) ``` public class ThreadPractice { static boolean canrunstatic; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { public void run() { int i = 0; while (!canrunstatic){i++;System.out.println("im still running");} System.out.println("finished"); } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); canrunstatic = true; } ``` So what is the logic behind this?