4

I have been recently trying to learn about threads and have been experimenting with them, and have come across something that confuses me. In the following code, the While loop running in the main thread never ends? However, when I add some body into the loop (eg. System.out.println("anything")), the loop does end and the app terminates.

package entire;

import java.util.ArrayList;
import java.util.List;

public class Worker implements Runnable{

boolean running = false;

Worker() {
    (new Thread(this)).start();
}

@Override
public void run() {
    running = true;
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    running = false;
    System.out.println(running);
}

public static void main(String[] args) throws InterruptedException {
    List<Worker> workers = new ArrayList<Worker>();
    workers.add(new Worker());
    workers.add(new Worker());
    workers.add(new Worker());

    for(Worker worker : workers) {
        System.out.println(worker);
        while(worker.running) {
        }
    }       
  }
}

If my while loop looks like this the app terminates?

    for(Worker worker : workers) {
        System.out.println(worker);
        while(worker.running) {
            System.out.println("literally anything");
        }
    }   

Can someone please explain why this is?

  • First of all, you shouldn't be waiting for threads to complete by doing a while loop... that defeats the purpose of threads because your main thread will still be consuming a lot of CPU doing nothing. However, that being said, this is still interesting behavior and I'm not sure why it happens. – nhouser9 Oct 04 '16 at 18:44
  • It might be related to your starting the thread in your Worker constructor. That time "this" is not yet ready made, and this can cause problems – Gábor Lipták Oct 04 '16 at 18:46
  • 1
    Try adding `volatile` to `boolean running` declaration. – Pshemo Oct 04 '16 at 18:47
  • 1
    Updating a non-volatile `boolean` isn't thread safe and can be inlined. Using a syncrhonized method prevents this optimisation. – Peter Lawrey Oct 04 '16 at 18:47
  • Hi, yea I was originally just experimenting to compare differences in how long it would take the main thread to execute code as compared to multithreading, but stripped all that when I came across this problem – Aaron Barnard Oct 04 '16 at 18:48
  • 1
    So you were only see the value of `running` change due to a method you called. It worked by accident until you took out that line. – Peter Lawrey Oct 04 '16 at 18:49
  • Adding the volatile keyword makes it run through! Can someone explain why that is? – Aaron Barnard Oct 04 '16 at 18:50
  • 1
    Take a look at the java memory model Aaron – Gábor Lipták Oct 04 '16 at 18:52
  • 1
    Did you visit duplicate question? It is linked at top of your question (you may need to refresh this page to see it). – Pshemo Oct 04 '16 at 18:52
  • That doesn't always happen sometimes program finishes on my machine. – GROX13 Oct 04 '16 at 18:52
  • Yea pshemo, thanks for adding that, I had tried researching similar questions but didn't look it up referring to the print statement, I assumed having anything in the body would make it work – Aaron Barnard Oct 04 '16 at 18:53
  • @Aaron see http://tutorials.jenkov.com/java-concurrency/java-memory-model.html : The values stored in the cache memory is typically flushed back to main memory when the CPU needs to store something else in the cache memory. The CPU cache can have data written to part of its memory at a time, and flush part of its memory at a time. It does not have to read / write the full cache each time it is updated. Typically the cache is updated in smaller memory blocks called "cache lines". One or more cache lines may be read into the cache memory, and one or mor cache lines may be flushed back ... – Gábor Lipták Oct 04 '16 at 18:58
  • So the copy of main thread of the fields of workers was invalidated and refreshed because the CPU needed the cache for something else (probably to write something out). Thats why the sysout helped. – Gábor Lipták Oct 04 '16 at 18:59
  • 1
    @GáborLipták I had just brought that link up myself, thanks for pointing me in the right direction! – Aaron Barnard Oct 04 '16 at 19:01
  • @AaronBarnard welcome – Gábor Lipták Oct 04 '16 at 19:02
  • 1
    @AaronBarnard apart from that your threading journey starts really nice here :) Awesome, that you wanted to understand whats happening. That is a good starting point. Keep up the good work :) – Gábor Lipták Oct 04 '16 at 19:04

0 Answers0