1

I asked to do a excersice of threading - 3 threads that will be a "runners" in a race and clicking ENTER will finish one of the threads run and return the time that took him to run.

Therefore I did this code -

Class of Runner :

import java.util.*;
public class Runner extends Thread {
    Date startDate;
    long startTime;    
    String name;
    private volatile boolean flag = true;

    //This method will set flag as false
    Runner(String name)
    {
        this.name = name;
    }
    public void stopRunning()
    {
        flag = false;
    }

    @Override
    public void run()
    {
        this.startDate = new Date();
        this.startTime = this.startDate.getTime();
        System.out.println(startTime);         
        while (flag)
        {
        }
        Date d = new Date();
        System.out.println(this.name + " Stopped Running....");
        System.out.println("The time that passed is " + Long.toString((d.getTime()-this.startTime)/1000) + " secondes" );
    }
}

Main :

import java.io.*;
public class Main {
    public static void main(String args[])
    {
        Runner run1 = new Runner("run1");
        Runner run2 = new Runner("run2");
        Runner run3 = new Runner("run3");
        run1.start();
        run2.start();
        run3.start();
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        run1.stopRunning();
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }

        run2.stopRunning();
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        run3.stopRunning();
    }
}

The code simply create 3 threads of Runner, than he is waiting for an ENTER input ( in my tests of the code I strangly had to get input 2 times for each ENTER instead of 1 ) after getting the ENTER input the thread stopRunning function is on and the thread stop running.

My problem is that when i run it ( on eclipse ) it tooks to java about 5 seconds to do thread.run() to all the three threads BUT when i tested it I found that if I add in the while(flag) loop on the Runner class, simple output like System.out.println(this.name) it works normally and java/eclipse compiles and runs its immidiatly

Someone know to explain me what happend or how can i slove it without adding this line?

Thanks alot,

Omer

1
  • Not answering your question, but please stop using try { System.in.read(); } catch (IOException e) { e.printStackTrace(); }. It has no purpose and only bloats you code. Handle an exception, if you can, otherwise, declare it and let it bubble up. You can make your main method 90% shorter and much better. Commented Dec 2, 2018 at 0:51

2 Answers 2

1

Unfortunately, I can't reproduce the behaviour you are describing. However, my guess is that using signal and await or notify and wait will fix the problem. Since notify and wait is far simpler to use, I chose to fix it like this:

import java.util.*;

public class Runner extends Thread {
    Date startDate;
    long startTime;    
    String name;
    private boolean flag = true;

    //This method will set flag as false
    Runner(String name)
    {
        this.name = name;
    }

    public synchronized void stopRunning()
    {
        flag = false;
        notifyAll(); //Think about if you really need the All
    }

    @Override
    public synchronized void run()
    {
        this.startDate = new Date();
        this.startTime = this.startDate.getTime();
        System.out.println(startTime);         
        while (flag) {
            try { //Just for the sake of compiling - you may think of a better solution
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace(); 
            }
        }
        Date d = new Date();
        System.out.println(this.name + " Stopped Running....");
        System.out.println("The time that passed is " + Long.toString((d.getTime()-this.startTime)/1000) + " secondes" );
    }
}

For an easy explanation of what may be happening on your system imagine your computer would be running one thread only. Now once you enter RunnerX.run a valid execution would be to get stuck in the while loop since there is no other thread that can change your bool-flag.
To prevent this, you want to "tell the ThreadRunner" to change the thread. (Because your program will only wait for the bool flag to change, your current thread does not need to be executed anymore.) You do this by calling wait (isn't this intuitive?).
Now you only need to guarantee to notify the thread that is still waiting that it can work again. You do this by calling notify.

What I just described is not 100% accurate but should give you an intuition about what's going wrong. Locks and conditions are really basic, you should probably extend your knowledge about this topic if you want to continue concurrent programming.

Sign up to request clarification or add additional context in comments.

Comments

0

Without the while(flag)-loop, your three threads nearly immediately finish, since they have no reason to wait after executing the few calls in the Run method.
That might already happen before the first try-block is entered.

I didn't test your code, but perhaps 'System.in.read' blocks for some time, which would be normal behaviour described in the docs:

https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.