I am writing a code using Java volatile keyword now and I am wondering why thread stops after I press enter for 2-3 times, not just 1 time. The code:
public class RunThread {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
myThread.shutDown();
}
}
class MyThread extends Thread {
public volatile boolean running = true;
public void run() {
while (running) {
System.out.println("Hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void shutDown() {
this.running = false;
}
}
Thanks in advance for you help!
CodePudding user response:
From the code, I would say that you are just too impatient.
You start main()
, that in turn triggers the new thread in MyThread
(that does not run yet!), then main()
starts an I/O operation that suspends it (the scanner.nextLine()
line).
Now the other thread will be executed, prints "Hello" and goes to sleep for a second – and it will not return to life before this second has elapsed, no matter how often you hit ENTER!
When you hit ENTER the first time, main()
proceeds, calls shutdown()
(that will set running
to false
) and terminates. But because MyThread
is not a demon thread, the JVM continues to run.
Now the second has elapsed, MyThread
checks running
(now false
) and terminates, too.
So the program terminates after your first hitting ENTER, but your conception of that is different … all consecutive ENTERs are going to /dev/null
or another type of limbo or void.
The answer from Isuru Perera shows how you can modify your code so that the program (and the JVM) terminates after the first ENTER.
CodePudding user response:
The volatile
keyword is used when you need to keep a variable only in the main memory, instead of duplicating the variable in CPU cache. So, using a volatile variable is not relevant to the problem you're having.
I believe when you press enter, the value of running
will become false. However, if the thread is asleep when you press enter, the program will not exit until the thread wakes up and starts the next iteration of the while loop. If you need to stop the thread immediately without waiting till it wakes up, you need to interrupt the thread. Use following code in your shutDown
method in order to interrupt the thread.
public void shutDown() {
this.running = false;
this.interrupt();
}