Why do threads behave differently with the other body of the run method?

This code is from Effective Java (paragraph 66): (without synchronization or instability, it 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 this chapter, he will never write "finished" to the console. I played with this class and add this line to the runnable run method:

 System.out.println("im still running"); 

In this case, the while loop not only increases i, but also displays this line in each cycle. But what drives me crazy, so the thread stops after 1 second when the main thread returns from sleep.

changed: (stops without mutability / synchronization)

 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?

+5
source share
2 answers

Precisely, it is simply not guaranteed that the thread will ever stop, but it is not forbidden that it stops. The logic behind this is the Java Memory Model , which is a rather complex topic, but necessary to understand multithreading in Java.

The concept is that writing to a non-volatile field of one stream is required only for viewing by another stream if these two actions are synchronized with each other. The compiler allows you to change the order of actions if the behavior shown by the thread in which it is executed does not change. But another thread can see it. Therefore, you need proper synchronization to tell the compiler that reordering is not allowed in some parts.

Read the full article about it here: JSR-133

+4
source

Writing data to the console is often implemented using streaming security.

In this case, your act of writing data to the console can also trigger an update to the canrunstatic variable, as shown by your backgroundThread .

Please note that this is not promised by the Java memory model, nor by the java System.out implementation

+2
source

Source: https://habr.com/ru/post/1213465/


All Articles