Reputation: 314
I need to shut down the application completely after ThreadPoolExecutor completes the currently executing tasks.For this I added the below code:
private void stopAppGracefully()
{
MyApplication.executor.shutdown();
System.exit(0);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.debug("Called the addShutdownHook()");
//Wait infinitely till executor shut down
while(!MyApplication.executor.isTerminated())
{
continue;
}
int queued = MyApplication.executor.getQueue().size();
int active = MyApplication.executor.getActiveCount();
int notCompleted = queued + active; // approximate
long submitted = MyApplication.executor.getTaskCount();
long completed = MyApplication.executor.getCompletedTaskCount();
long notCompleted2 = submitted - completed; // approximate
logger.debug("App is down..queued...:"+queued);
logger.debug("App is down..active...:"+active);
logger.debug("App is down..queued + active...:"+notCompleted);
logger.debug("App is down..submitted...:"+submitted);
logger.debug("App is down..completed...:"+completed);
logger.debug("App is down..submitted - completed...:"+notCompleted2);
System.gc();
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
for (int i = 0; i < threadArray.length; i++)
{
logger.debug("Remaining threads: "+ threadArray[i].getName());
}
}
});
}
But I see the below information in logs:
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 292 - App is down..queued...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 293 - App is down..active...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 294 - App is down..queued + active...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 296 - App is down..submitted...:43
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 297 - App is down..completed...:43
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 298 - App is down..submitted - completed...:0
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Finalizer
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Reference Handler
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-3
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-2
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Thread-1
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: main
20 Jul 2017 05:03:17 DEBUG | ApplicationDirectoryWatcher | run | 307 - Remaining threads: Signal Dispatcher
Still seven threads are active. How to kill/stop these threads ?
I need to stop/kill all the threads belonging to the application.
Upvotes: 0
Views: 1283
Reputation: 128
From the Java documentation we see that the System.exit( int )
method basically does the same work as manually calling the Runtime.getRuntime().exit( int )
method. Then again, have a look at the Java documentation of the addShutdownHook( Thread )
method. Quoting that:
Once the shutdown sequence has begun it is impossible to register a new shutdown hook or de-register a previously-registered hook. Attempting either of these operations will cause an IllegalStateException to be thrown.
Having read this, you probably have a synchronization error, in which the VM starts preparing the halting phase when the System.exit( int )
method is executed, but then, before the actual shutdown sequence starts, the addShutdownHook( Thread )
line is executed. The result is that it tells you there are threads running because effectively, they are, since the VM hasn't completely shut down yet.
Upvotes: 0
Reputation: 206816
ExecutorService.shutdown()
does not immediately kill all running tasks and stop all threads. It will continue to run the tasks that are currently running. Note that shutdown()
doesn't wait - it immediately returns, and current tasks may at that point still be running.
You can call awaitTermination(...)
to wait for the currently running tasks to finish, or shutdownNow()
which does indeed attempt to kill all currently running tasks.
To attempt to shutdown an ExecutorService
gracefully, and then forcefully if it doesn't stop within a certain amount of time, you can use the following:
// Initiate graceful shutdown
executorService.shutdown();
try {
// Wait one minute for tasks to finish
boolean terminated = executorService.awaitTermination(1L, TimeUnit.MINUTES);
if (!terminated) {
// If not terminated after one minute, shutdown forcefully
executorService.shutdownNow();
}
} catch (InterruptedException e) {
System.err.println("Interrupted while awaiting termination");
}
Upvotes: 2
Reputation: 15842
On Linux, you can use kill -9
with PID. On Windows, go to task manager and end task
.
Upvotes: 0