GerMex GerMex - 28 days ago 6
Java Question

Terminating Thread.Sleep() when another Thread terminates?

I keep getting an interrupt from a thread within a thread and it won't let me destroy the main thread because of it. I would still like to use Thread.sleep() to slow down the loop.

Main Thread:

startEngine.setOnAction((ActionEvent e) -> {

executor.submit(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
lifeInstance.runEngine();
}

}

});

});

stopEngine.setOnAction((ActionEvent e) -> {
executor.shutdownNow();
});


executor.submit is calling lifeInstance.runEngine() which is:

public void runEngine() {

//logic...

try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(LifeEngine.class.getName()).log(Level.SEVERE, null, ex);

return;
}
}


ERRROR:

//Prints out stuff from runEngine()

Nov 06, 2016 6:04:52 PM thecell.LifeEngine runEngine
SEVERE: null
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thecell.LifeEngine.runEngine(LifeEngine.java:66)
at UIControls.RightControls$1.run(RightControls.java:48)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)


//Keeps printing out stuff from runEngine()

Answer

Because isInterrupted() returns false, when the runEngine() method returns on the InterruptedException.

From the book "Java Concurrency in Practice":

Blocking library methods like Thread.sleep and Object.wait try to detect when a thread has been interrupted and return early. They respond to interruption by clearing the interrupted status and throwing InterruptedException, indicating that the blocking operation completed early due to interruption.

The interrupted state is cleared when you get the exception. You can reset it before return:

} catch (InterruptedException ex) {
    Logger.getLogger(LifeEngine.class.getName()).log(Level.SEVERE, null, ex);
    Thread.currentThread().interrupt();
    return;
}

Actually, you should do this because your task code is executed by a thread pool, and it's good behaviour to preserve the interrupted state after your task code has processed it. So that the thread pool can respond to the interruption as well.

Comments