Stop threads before close my JavaFX program - java

I'm having a problem with closing my application because some threads are still running after I close the application.
Somebody can help me with some method to stop all Threads being executed in background before killing the main thread???
[EDITED]
With my questions about javafx I have noticed that many newer developers are facing problem managing Threads. I would like to share what I have done to simplify my life about managing threads on javafx. I've created an AsyncTask class based on AsyncTask from Android that basically do the same of Android's in a humble but effective way. You can find more information about it on Github project

You have three options here - the easiest is to simply create your Threads as deamons, which means that when your main program ends all deamon threads will terminate too.
Thread thread = new Thread();
thread.setDaemon(true);
Thats easiest, but the downside is that you wont get a graceful shutdown (ie the threads will stop, you wont get a chance to peform resource management etc, which may or may not be a problem for you).
The alternative is to keep a hold on the spawned threads and when your program receives the signal to close you iterate over the threads and pass in a signal of some sort to signa that they too should terminate
volatile boolean shutdown = false;
public void shutdown() {
shutdown = true;
}
public void run() {
while(!shutdown) {
... do your work here
}
... perform any cleanup work here
(Note: ignores any exception handling for clarity)
The last option is to use the Executor framework in java.util.concurrent
ExecutorService executorService = Executors.newFixedThreadPool(10);
... assign/invoke tasks etc
... at some point later your program is told to shutdown
... shutdown in executor too
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS); // wait for 10s in this case
executorService.shutdownNow();

Better way to fix this is add the EventHandler on Close Request:
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent e) {
Platform.exit();
System.exit(0);
}
});
}

Override your Application Class
//System.exit(0) This will close all timers and threads inside the Jar application...
#Override
public void stop() throws Exception {
super.stop(); //To change body of generated methods, choose Tools | Templates.
System.exit(0);
}

Executors from the java.util.concurrent package are the way to go. Explicitly:
ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable runnable) {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
}
});
Java 8 version with fixed ScheduledExecutorService
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1, r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);
thread.setDaemon(true);
return thread;
});

The method Platform.exit() belongs to the JavaFX context.
When you call Platform.exit(), the method javafx.application.Application#stop() is called before the context terminates.
Put inside the stop() method everything that needs to be executed before the JavaFX context terminates.
With the System.exit(0) method, the application terminate abruptly.
This method is not secure because if at the moment you call System.exit(0) and a Job is still running, maybe executing a write in the database,
the application will not wait the Job fihish resulting in a corrupted database.
I have an application running JavaFX with SpringBoot and a thread pool. That is how I handle it.
//...
import javafx.application.Application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
#SpringBootApplication
public class Main extends Application {
ConfigurableApplicationContext context;
ScheduledExecutorService scheduledExecutorService;
#Override
public void init() {
this.context = SpringApplication.run(getClass());
this.context.getAutowireCapableBeanFactory().autowireBean(this);
this.scheduledExecutorService = Executors.newScheduledThreadPool(10);
}
#Override
public void stop() throws Exception {
super.stop();
this.context.close();
this.scheduledExecutorService.shutdownNow();
}
// ...
}

Related

Executor Service setting the flag to stop the thread

I am running simple thread which has run method as follows
public run()
while(!stopFlag){
// print something Line 1
// print something Line 2
// print something Line 3
// print something Line 4
}
If I run this thread through ExecutorService viz
ExecutorService exs = Executors.newFixedThreadPool(5);
exs.execute(new MyThread));
I stop the ExecutorService
exs.shutdown();
But this does not stop the thread as flag is not set to false. In another question related to same topic I was asked to properly handle InterruptedException which is caused when exs.shutdown() is called.
But in this case I am not doing any action that can throw InterruptedException.
What is the standard way to handle such case ?
Further question
Answer given by Sabir says "If your runnable doesn't respond well to interrupts, nothing can be done to stop it other than shutting down the JVM. ".This seems to be my case.
But how to introduce handling of InterruptedException; if I am not calling any method that throws interrupted exception?
If you are willing to shut your thread even if that flag remains true, you should use - ExecutorService.shutdownNow() method instead of ExecutorService.shutdown()
Quoting from Java Docs,
shutdown()
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
This method does not wait for previously submitted tasks to complete
execution. Use awaitTermination to do that.
shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
This method does not wait for actively executing tasks to terminate.
Use awaitTermination to do that.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt, so any task that fails to respond to
interrupts may never terminate.
For standard way, I will quote from JDK example from ExecutorService interface,
Usage Examples
Here is a sketch of a network service in which threads in a thread pool service incoming requests. It uses the preconfigured Executors.newFixedThreadPool factory method: class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorService pool;
public NetworkService(int port, int poolSize)
throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize); }
public void run() { // run the service
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
} } }
class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() {
// read and service request on socket } }} The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks: void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
} } catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt(); } }}
Notice that there are no guarantees even with shutdownNow() .
EDIT : If I change your while(!stopFlag) to while(!Thread.currentThread().isInterrupted()) then thread with conditional loop get shutdown with shutdownNow() but not with shutdown() so thread gets interrupted with shutdownNow(). I am on JDK8 and Windows 8.1. I do have to put a sleep in main thread so that service can get time to set up the service and launch runnable. Thread gets launched, goes in while then stops when shutdownNow() is called. I don't get that behavior with shutdown() i.e. thread never comes out of while loop. So the approach to make your runnables responsible for interrupts should be there ,either by checking flags or handling exceptions. If your runnable doesn't respond well to interrupts, nothing can be done to stop it other than shutting down the JVM.
One good approach is shown here
well from your question I am assuming that you are trying to shutdown the process gracefully. In order to do so you need to register a shutdownHook to achieve it. Here is a sample code to achieve it.
package com.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadManager {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThread = null;
#Override
public void run(){
System.out.println("Shutting down....");
this.myThread.stopProcess();
}
public Thread setMyThread(MyThread myThread){
this.myThread=myThread;
return this;
}
}.setMyThread(myThread));
ExecutorService exs = Executors.newFixedThreadPool(5);
myThread.setName("User");
exs.execute(myThread);
exs.shutdownNow();
}
}
And in MyThread.java will be look like following:-
package com.example;
public class MyThread extends Thread{
private boolean stopFlag;
#Override
public void run(){
while(!stopFlag){
System.out.println(this.getName());
}
}
public void stopProcess(){
this.stopFlag=true;
}
}
Now if you make a jar file of this code and run the in a Linux server to see how it is working, then follow these additional steps
Step 1> nohup java -jar MyThread.jar &
Press ctrl+c to exist
Now find the pid using following command
Step 2> ps -ef| grep MyThread.jar
Once you got the pid than execute the following command to stop gracefully
Step 3>kill -TERM <Your PID>
When you check the nohub.out file, the output will looks something like following
User
User
.
.
.
User
Shutting down....
User
.
.
Remember if you try to shutdown using kill -9 than you will never see the Shutting down.... message.
#Sabir already discuss the difference between shutdown and shutdownNow. However I will never recommend you to use interrupt call while the threads are running. It might cause memory leak in real time environment.
Upadte 1:-
public static void main(String[] args) {
MyThread myThreads[] = new MyThread[5];
ExecutorService exs = Executors.newFixedThreadPool(5);
for(int i=0;i<5;++i){
MyThread myThread = new MyThread();
myThread.setName("User "+i);
exs.execute(myThread);
myThreads[i] = myThread;
}
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThreads[] = null;
#Override
public void run(){
System.out.println("Shutting down....");
for(MyThread myThread:myThreads){
myThread.stopProcess();
}
}
public Thread setMyThread(MyThread[] myThreads){
this.myThreads=myThreads;
return this;
}
}.setMyThread(myThreads));
exs.shutdownNow();
}

Stopping a thread in an executor service

I am faced with a situation where I need to stop a thread of Executor service from running.
I have already read the solution in other posts which says to make use of Future object and cancel the task.
But I rather tried a different approach.
Please can anyone let me know if there is any issue with this approach.
Following is my Runnable class.
public class TestRunnable implements Runnable {
Thread t;
#Override
public void run() {
// TODO Auto-generated method stub
setT(Thread.currentThread());
while(true)
{
if(Thread.currentThread().isInterrupted())
{
System.out.println("From Inside thread, Exiting");
System.exit(0);
}
}
}
public void setT(Thread t) {
this.t = t;
}
public Thread getT() {
return t;
}
}
Following is my main method:
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ruunTest {
public static void main(String[] args) throws IOException, InterruptedException {
// TODO Auto-generated method stub
ExecutorService service = Executors.newCachedThreadPool();
TestRunnable test = new TestRunnable();
service.execute(test);
Thread.sleep(1000);
System.out.println("About to Interrupt");
test.getT().interrupt();
}
}
The only proper way to do this is to cancel the Future corresponding to your task and in your task, you should check regularly if the thread has been interrupted or not.
Something like that:
public class Task implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
while(true) {
// Check regularly in your code if the thread has been
// interrupted and if so throws an exception to stop
// the task immediately
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Thread interrupted");
}
}
}
}
Then your main code would be:
ExecutorService service = Executors.newCachedThreadPool();
// My task
Task task = new Task();
// Submit the task and get the corresponding future
Future<?> future = service.submit(task);
...
// Cancel the task which will interrupt the thread that was executing the
// task if any
future.cancel(true);
Not a good idea to stop a thread voluntarily. Your code is not stopping a thread it actually blocking the whole JVM form progressing further. You actually are missing the whole point of the executor service.
The ideology of the executor is that 'I' have an expanding / contracting list of threads that will do the work for you. 'You' just give me individual, mutually exclusive work jobs to action (Runnables or Callables). The main point to understand here is "you don't worry about threads and their life cycle" ... you just create work items and give them to me to execute. If you don't want to execute a work or want to stop in middle call the cancel method, else don't worry about it, because once its done 'I' will finish and clean up and provide you the return values if any.
'I' will also manage the thread pool for you but expanding it with more threads when work jobs come in faster and contracting it to lesser threads by "closing idle threads" when jobs are less frequently pouring in.
Now tell me, is it right what you are trying to achieve.
You can use Quasar library for threads, works faster that Java native threads and are easier to use.
http://www.paralleluniverse.co/quasar/
Try to thread.interrupt() but it is not recommended.
You can use thread.stop , although it will throw threadDeathError which needs to be handled.
If you use future.cancel, it will cancel the task but wont kill the thread as thread will go back to thread pool. Thread.stop will kill the thread.

Java add shutdown hook inside method

In my code I'm using CompletionService and ExecutorService in order to start a bunch of Thread to execute some task (that can take a lot of time).
So I have a method that creates the ExecutorService and the CompletionService, then starts submitting threads and then take the results.
I would like to add a shutdown hook in order to gracefully shutdown the executor (I know that probably I should handle releasing resources instead of executor shutdown but in my case each thread has its own resources so shutting down them gracefully can be a good soulution I suppose).
For this reason I write the following code
public Class myClass{
...
private CompletionService<ClusterJobs> completion;
final long SHUTDOWN_TIME = TimeUnit.SECONDS.toSeconds(10);
...
public Message executeCommand(Message request){
final ExecutorService executor = Executors.newFixedThreadPool(30);
completion = new ExecutorCompletionService<ClusterJobs>(executor);
....//submit and take results
Runtime.getRuntime().addShutdownHook(new Thread(){
#Override
public void run() {
logger.debug("Shutting down executor");
try {
if (!executor.awaitTermination(SHUTDOWN_TIME, TimeUnit.SECONDS)) {
logger.debug("Executor still not terminate after waiting time...");
List<Runnable> notExecuted= executor.shutdownNow();
logger.debug("List of dropped task has size " + droppedTasks.size());
}
}catch(InterruptedException e){
logger.error("",e);
}
}
});
}
}
Do you think that this is a reasonable solution or it's unsafe to register and unregister shutdown hook using local classes?
Thanks in advance
Regards
From Design of the Shutdown Hooks API:
Simple shutdown hooks can often be written as anonymous inner classes, as in this example:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { database.close(); }
});
This idiom is fine as long as you'll never need to cancel the hook, in which case you'd need to save a reference to the hook when you create it.

Java thread pool, how to stop a long running thread immediately using shutdownNow()?

I have a main thread that creates several threads using Executors
ExecutorService executor = Executors.newFixedThreadPool(4);
Each thread has long running jobs (some legacy code from another team) which might run for hours.
Now I want to shutdown from the main thread using
executor.shutdownNow()
And I want the threads to be able to stop immediately, how could I do that?
In the thread, say we have such code:
public void run() {
doA();
doB();
doC();
...
...
}
Now my issue is, even if I called shutdownNow, the running thread will run to the end then stop. I'd like to know how to stop and exit.
It's a slightly tricky situation indeed!
Can we make use of a hook that the JDK has provided in the form of ThreadFactory that is consulted when the associated thread pool is creating a thread in which your legacy task will run? If yes, then why not make your legacy code run in a daemon thread? We know that the JVM exits when the last non-daemon thread exits. So, if we make each thread that the thread pool uses to run your legacy tasks a daemon thread, there is a chance that we can make the shutdownNow() call more responsive:
public class LegacyCodeExecutorEx {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2, new DaemonThreadFactory());
executor.submit(new LegacySimulator());
Thread.sleep(1000);
executor.shutdownNow();
}
static class LegacySimulator implements Runnable {
private final AtomicLong theLong;
LegacySimulator() {
theLong = new AtomicLong(1);
}
#Override
public void run() {
for (long i = 10; i < Long.MAX_VALUE; i++) {
theLong.set(i*i);
}
System.out.println("Done!");
}
}
static class DaemonThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("Daemon Thread");
t.setDaemon(true);
return t;
}
}
}
If you play with setDaemon(true) line, you will see that this code either responds to the exit of the main thread (which is non-daemon) either immediately or takes its own sweet time to finish the task.
Is making your legacy-code-running threads daemon threads a possibility? If yes, you could give this a try.
You need to include a flag in the Runnable object instantiation that checks between tasks whether you need to stop or not.
public void run() {
if(timeToShutdown) return;
doA();
if(timeToShutdown) return;
doB();
/*etc*/
}
Threads in Java operate at a (relatively) low level. Short of directly shutting down the entire JVM, the only way to manually force the stop of a Thread is using Deprecated behavior from Java 1.0/1.1, which pretty much noone wants you to use.

How to manage worker thread lifecycles when main Java thread terminates?

I want to achieve the following: When my application starts, the main thread will start 1+ worker threads that should run in the background, and periodically do things behind the scenes. These should not block the main thread: once main starts the workers, it continues doing its own thing until:
The main thread finishes (normal application termination) - in the case of a command-line utility this is when the end of the main(String[]) method is reached; in the case of a Swing GUI it could be when the user selects the File >> Exit menu, etc.
The operating system throws a kill command (SIGKILL, etc.)
An unexpected, uncaught exception occurs in the main thread, effectively killing it (this is just an unpolite version of #1 above)
Once started/submitted from the main thread, I want all the worker threads (Runnables) to essentially have their own life cycle, and exist independently of the main thread. But, if the main thread dies at any time, I want to be able to block (if at all possible) the main thread until all the workers are finished shutting down, and then "allow" the main thread to die.
My best attempt so far, although I know I'm missing pieces here and there:
public class MainDriver {
private BaneWorker baneWorker;
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
MainDriver driver = new MainDriver();
driver.run();
// We've now reached the end of the main method. All workers should block while they shutdown
// gracefully (if at all possible).
if(executor.awaitTermination(30, TimeUnit.SECONDS))
System.out.println("Shutting down...");
else {
System.out.println("Forcing shut down...");
executor.shutdownNow();
}
}
private void run() {
// Start all worker threads.
baneWorker = new BaneWorker(Thread.currentThread());
// More workers will be used once I get this simple example up and running...
executor.submit(baneWorker);
// Eventually submit the other workers here as well...
// Now start processing. If command-line utility, start doing whatever the utility
// needs to do. If Swing GUI, fire up a parent JFrame and draw the application to the
// screen for the user, etc.
doStuff();
}
private void doStuff() {
// ??? whatever
}
}
public class BaneWorker implements Runnable {
private Timer timer;
private TimerTask baneTask;
private Thread mainThread;
public BaneWorker(Thread mainThread) {
super();
this.mainThread = mainThread;
}
#Override
public void run() {
try {
timer = new Timer();
baneTask = new TimerTask() {
#Override
public void run() {
System.out.println("When the main thread is ashes...");
}
};
// Schedule the baneTask to kick off every minute starting now.
timer.scheduleAtFixedRate(baneTask, new Date(), 60 * 1000);
} catch(InterruptedException interrupt) {
// Should be thrown if main thread dies, terminates, throws an exception, etc.
// Should block main thread from finally terminating until we're done shutting down.
shutdown();
}
}
private void shutdown() {
baneTask.cancel();
System.out.println("...then you have my permission to die.");
try {
mainThread.join();
} catch(InterruptedException interrupt) {
interrupt.printStackTrace;
}
}
}
Am I on-track or way off-base here? What do I need to change to make this work the way I need it to? I'm new to Java concurrency and am trying my best to use the Concurrency API correctly, but stumbling around a bit. Any ideas? Thanks in advance!
The main thread must signal the worker threads to terminate (generally this is achieved just by using a flag) and then it should call join on every thread to wait for their termination. Have a look here: Java: How to use Thread.join
You can use Runtime.addShutdownHook to register an un-started thread that is executed when a JVM is terminated, the system is shutting down etc. This code can do some cleanup itself, or perhaps notify running daemon threads to finish their work. Any such cleanup code must be relatively fast, because on many systems programs have only a limited time to do cleanup before they're forcibly terminated.
Perhaps you could also consider making your background thread daemon threads. Then they will not block the JVM when main finishes and will be still running during the clean-up phase.
Note that you can't intercept SIGKILL - this signal is designed to be unavoidable and immediate. But it should work with SIGTERM, SIGHUP and similar signals.
Update: You can easily create ExecutorServices that run daemon threads. All you need is to create a proper ThreadFactory:
public static class DaemonFactory
implements ThreadFactory
{
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
than you create an ExecutorService like
public static void main(String argv[])
throws Exception
{
ExecutorService es
= Executors.newCachedThreadPool(new DaemonFactory());
// ^^^^^^^^^^^^^^^^^^^
es.submit(new Callable<Object>() {
public Object call() throws Exception {
Thread.sleep(100);
System.err.println("Daemon: " +
Thread.currentThread().isDaemon());
return null;
}
});
// Without this, JVM will terminate before the daemon thread prints the
// message, because JVM doesn't wait for daemon threads when
// terminating:
es.awaitTermination(3, TimeUnit.SECONDS);
}
Concerning Thread.join(), you shouldn't try to use it on threads managed by an ExecutorService. It's the responsibility of the executor to manage them. You have no reliable way how to enumerate its threads, the executor can create and destroy threads depending on its configuration etc. The only reliable way is to call shutdown(); and then awaitTermination(...);.
If SIGKILL is a unix "kill -9" there's nothing you can do about it.
For graceful exits, use a try/catch/finally in your main. The catch will catch your exceptions and allow you to do what needs to be done (recover? abort?) The finally will give you the hook to spin down your threads gracefully.
Reviewing your code quickly, I don't see where you're keeping track of your thread instances. You'll need those if you're going to tell them to spin down.
psuedocode:
static Main(...) {
ArrayList threads = new ArrayList();
try {
for (each thread you want to spin up) {
threads.add(a new Thread())
}
}
catch { assuming all are fatal. }
finally {
for(each thread t in threads) {
t.shutdown();
t.join(); /* Be prepared to catch (and probably ignore) an exception on this, if shutdown() happens too fast! */
}
}

Categories

Resources