I am using Guava's SimpleTimeLimiter to get Timeout functionality. The problem is that shutting down the app (if it's finished) take 30s as soon as i use the SimpleTimeLimiter (this time does not change if i change timeout). If i call new MyCallable().call() directly all works fine - app is shut down as soon as last task is finished.
The app itself has an own shutdown hook to be able to handle ctrl-c (to finish last task). The app uses a H2- embedded db and Network.
I tried to profile with visualvm - the time at the end is not recorded?! This long waiting period tooks placed before my shutdown hook is called (probably another shutdown hook?).
Any ideas how to fix this?
When you create SimpleTimeLimiter with default constructor - he create own Executors.newCachedThreadPool() that you can't control, So your application what until all threads will be completed. from Javadoc
... Threads that have not been used for sixty seconds are
terminated and removed from the cache....
If you create own ExecutorService and create SimpleTimeLimiter with this executorService then you can shutdown executorService on your shutdown hook.
private final ExecutorService executor;
private final TimeLimiter timeLimiter;
...
executor = Executors.newCachedThreadPool();
timeLimiter = new SimpleTimeLimiter(executor);
...
public void shutdown() {
if (executor == null || executor.isShutdown()) {
return;
}
executor.shutdown();
try {
executor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.log(Level.WARNING, "Interrupted during executor termination.", e);
Thread.currentThread().interrupt();
}
executor.shutdownNow();
}
Related
I have a web app which runs an interface for controlling an irrigation system. The system starts up to 10 or so threads, using a ScheduledThreadPoolExecutor.
I have found that when I close down the server, many of these threads continue to run. From the Tomcat catalina.out log:
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [GH2] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak.
The classes that start these threads are dotted around my app. In order to try to have some control over stopping them, I have a single ScheduledThreadPoolExecutor created by a ServletContextListener and passed into each of the classes that might start a task.
I have tried setting properties in the ScheduledThreadPoolExecutor that I assumed would close down all threads when contextDestroyed() is called in the listener:
public void contextInitialized(ServletContextEvent event) {
executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(10);
executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
executor.setRemoveOnCancelPolicy(true);
event.getServletContext().setAttribute("executor", executor);
Here is a typical bit of code that schedules a thread:
public WeatherScheduler(ScheduledThreadPoolExecutor executor) {
this.executor = executor;
checkEveryHour();
}
public void checkEveryHour() {
final Runnable weatherChecker = new Runnable() {
public void run() {
if (!Thread.interrupted()) {
if (Date_TimeUtils.isBetween7amAnd8pm()) {
weather = new Weather();
weather.getNewForecast();
IrrigationLogger.getInstance().logEvent("weather forecast: " + weather.toString());
} else
LOGGER.log(Level.INFO, "weatherChecker not called as isBetween7amAnd8pm() == false ");
}
}
};
// delay of a minute to allow for getting internet connection, repeat every hour
executor.scheduleAtFixedRate(weatherChecker, 1, 60, TimeUnit.MINUTES);
}
When the server is closed down, the contextDestroyed() method is called in the listener, and I have
executor.shutdownNow();
included in that method.
But still I get the message in the log file that threads have been started that can't be stopped.
What am I missing?
Thanks.
The way any ThreadExecutor tries to stop a currently running thread is by setting interrupt flag by invoking Thread class method interrupt() on that thread. It is responsibility of the running thread to detect that it was "asked" to finish, so the running thread should clean up and terminate once the signal received. So first in your runner code surround it with try-catch where you will catch InterruptedException and also in your runner code you suppose to invoke method Thread.currentThread().isInterrupted() and if it returns true clean up and finish the thread (same as in your catch statement)
I have a web application that contains a java bean for executing a potentially long-running job. I'd like to find a way that I can identify when a thread has been executing for a very long time and then potentially kill it if necessary.
My application runs in Glassfish 3 so I am on Java 1.6. I am just looking for a solution to a potential problem in the future.
EDIT:
To be clear I am looking for something like a tool or utility to monitor a running web application.
Use an Executor Service.
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Runnable(){ ....});//pass your runnable
And then you can wait for a specified time:
try {
int timeOut = 5;
//Waits if necessary for at most the given time for the computation to
// complete, and then retrieves its result, if available.
future.get(timeout, TimeUnit.SECONDS)
} catch (TimeoutException e) {
System.out.println("TimedOut!");
}
executor.shutdownNow();
I have a few executor services which schedule local tasks such as reading a file, connecting to db etc. These processes do huge amount of logging, which is extensive based on the fact there are many threads running concurrently, writing their own thing into the log.
Now, at some point in time an exception can be raised, which reaches the main method where all exceptions are caught. I am then shutting down all the services and cancelling each task, hoping to prevent all further messages to the log. Unfortunately, the messages are still showing up after I shut everything down... Any ideas?
UPDATE:
Here is some code
public class Scheduler{
private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;
...
public void shutDown() {
service.shutdownNow();
for (Future task : cache.values())
task.cancel(true);
}
The task will carry on running until it reaches a point where it detects the Thread has been interrupted. This can happen when calling some System or Thread functions and you may get an exception thrown. In your case you probably need to check yourself by calling
Thread.currentThread().isInterrupted()
It is a good idea to do this if your code runs loops and you are expecting to be stopped in this way.
When you shutdownNow your executor or call cancel(true) (by the way shutdownNow already cancels the already submitted tasks so your loop is unnecessary) your tasks get interrupted.
Depending on how they react to the interruption, they might then:
stop what they are doing immediately
stop what they are doing after a while, because the interruption signal is not being checked regularly enough
continue doing what they are doing because the interruption signal has been ignored
For example, if your tasks run a while(true) loop, you can replace it with something like:
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
cleanup();
//and exit
Another example:
for (int i = 0; i < aBigNumber; i++) {
if (Thread.currentThread().isInterrupted()) { break; }
//rest of the code for the loop
}
cleanup();
//and exit
Another example, if you call a method that throws InterruptedException:
try {
Thread.sleep(forever); //or some blocking IO or file reading...
} catch (InterruptedException e) {
cleanup();
Thread.currentThread.interrupt();
//and exit
}
Executors support 2 approaches of shutdown
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.
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.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
Ref : http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
- Try using the shutdowNow() method, it will shutdown all the task started by this Executor throwing InterruptedException, but IO and Synchronized operation can't be interrupted.
Eg:
ExecutorService executor = Executors.newFixedThreadPool();
executor.execute();
...
...
executor.shutdownNow();
- cancel(true) method can be used with submit() method to shutdown a particular task.
i want to stop all the submitted tasks on an ExecutorService but i couldn't find a method to do it. any suggestions ?
Take a look at ExecutorService.shutdownNow.
for example, var pool is an ExecutorService.
//start a task
pool.execute(task);
//
try {
pool.shutdown();
if(!pool.awaitTermination(awaitTime, TimeUnit.MILLISECONDS)){
pool.shutdownNow();
}
} catch (InterruptedException e) {
pool.shutdownNow();
}
A deterministic shutdown for any task submitted to ExecutorService is possible only when the task itself is designed to respond to a external signal ( such as an Interruption on the thread running the task , or some other application designed flag ). ExecutorService itself only helps in as much as it will raise these signals for you ( when you call its shutdown() and shutdownNow() methods ) and notify all running tasks. If you want to be able to shutdown all tasks ( including the ones which are already running and not yet finished ) then design these tasks to have a cancellation policy.
I have a Runnable implementation that does some work which might take some time and I am trying to schedule it using ScheduledThreadPoolExecutorwith scheduleAtFixedRate method. Now I want to ensure that shut down is graceful that means, Before terminating, task should be allowed to run completely. I have written following code for shutdown.
public void shutDown() throws Exception {
try {
LOG.info("Gracefully shutting down executor");
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) {
// cancels currently executing tasks.
LOG.info("Executor is still alive. Forcing executor thread pool to shut down");
executor.shutdownNow();
// Wait a while for tasks to respond to being cancelled
if (!executor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS)) {
LOG.fatal("Executor thread pool did not terminate");
throw new Exception("Unable to shut down executor thread pool forcefully");
}
LOG.info("Executor shut down.");
}
} catch (Exception e) {
LOG.error("Exception shutting down executor", e);
throw e;
}
}
But problem with this is, I have to specify time to wait explicitly and I can not predict time taken by task in advance. Is there a way to make executor wait indefinitely until executing task finishes without having to mention time to wait? Or is there a better way to work on above scenario?
Thanks
Jitendra
Simplest solution is to "overprovision" so to speak. I suggest you use a huge timeout period that in no way can be exceeded by the time needed for a single task to execute, like:
// do you have tasks that can take more than 2^63 - 1 days to finish? :)
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
Use shutdown() to begin a graceful termination, and then use awaitTermination(long, TimeUnit) to wait for the executor service to finish shutting down.
As it was noted in the comment executor.shutdown() is not forcing any tasks to exit but rather it prevents new ones from being accepted. Have a look in the javadoc.
Another advice is if you want to get hold of your tasks as soon as they complete, you can implement Callable<T> instead of a Runnable that it's of a generic type and returns a value of type T. Then you can wrap this Callable<T> into a FutureTask<V> and submit that to your ScheduledThreadPoolExecutor. You can then loop through your tasks as soon as they have completed their work and are available. So in short something like this (notice as soon as we are done loading the scheduler with tasks it's safe to shut it down meaning that we don't allow any further tasks to be submitted from then on):
ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(n);
Callable<Integer> myTask = . . .;
FutureTask<Integer> task = new FutureTask<Integer>(myTask);
schedulerExecutor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
schedulerExecutor.shutdown();