Im writing an SDK that has a singleton class with ExecutorService. It looks something like this:
public class MySingleton {
private static MySingleton mInstance;
private ExecutorService mExecutorService;
private MySingleton() {
mExecutorService = Executors.newSingleThreadExecutor();
}
// ...
public void doSomething(Runnable runnable) {
mExecutorService.execute(runnable);
}
}
This SDK class is intended to be used throughout the application to run tasks/Runnables, and doSomething() function is to queue and run all Runnables in a single thread.
But one thing I couldn't figure out is when to call the ExecutorService.shutdown() method. If I call it like so:
public void doSomething(Runnable runnable) {
if (mExecutorService.isTerminated()) {
mExecutorService = Executors.newSingleThreadExecutor();
}
mExecutorService.execute(runnable);
mExecutorService.shutdown();
}
It would defeat the purpose of using one Thread because if the old Runnable is still running when doSomething() is called the 2nd time, there may be two different Threads running simultaneously. Of course I can have a function that manually shuts down the ExecutorService, but requiring the user of the SDK to explicitly call the shutdown function didn't seem appropriate.
Can anyone show me some tips on when/how to call ExecutorService.shutdown() in an Android application? Thanks
There is no good reason to call shutdown each time you execute some task. You might want to call shutdown when some part of your application is being closed/finished. Ie. when Service is being stopped - then if it used executors - then I suppose you should shutdown them - but actually the point is to allow all the tasks to finish before the service quit logic will perform some finishing code. ie. by using:
executors.shutdown();
if (!executors.awaitTermination(5, TimeUnit.SECONDS)) {
executors.shutdownNow();
}
as an example, such service could be used to download some files, user would ie. want to pause downloading - ie. by opening camera application (that might stop your application/service to reclaim its resources/memory).
In an Android application, there is no need to shutdown a singleton ExecutorService unless it has any idle thread. According to Android docs:
A pool that is no longer referenced in a program AND has no remaining
threads will be shutdown automatically. If you would like to ensure
that unreferenced pools are reclaimed even if users forget to call
shutdown(), then you must arrange that unused threads eventually die,
by setting appropriate keep-alive times, using a lower bound of zero
core threads and/or setting allowCoreThreadTimeOut(boolean).
So if you use Executors.newCachedThreadPool() or create a ThreadPoolExecutor with corePoolSize of 0, it will automatically be shutdown when the application process dies.
Related
We have the problem that there are multiple async threads that process a bunch of data and need minutes or some of them even hours to end. The pod also processes some other short running request.
It might occur that the pod has to be moved, and a shutdown will happen during this processing. In this case, we want the threads to finish their work in short term and leave a status, which we can use to process the remaining data.
We already use graceful.shutdown=enable.
The idea now is that we introduce a method with #PreDestroy in the bean that creates the async threads.
When this method is called, it will set a "shutdown" flag in a different bean. All the long-running threads check this flag during processing and will stop processing when it's true and write a clean state of their processing to the database.
This is more or less working ... but not all the time.
As I understood after getting the shutdown trigger at first, there is a configurable time spring.lifecycle.timeout-per-shutdown-phase where threads can continue processing their work without reduction in any of the needed resources. After the time is over, all the shutdownhooks are processed in an unknown order. This brings me to the thought that I might not have all the necessary resources for leaving a clean state, when I use the approach with the #preDestroy and the flag.
Is there a better solution to this?
Is there a need to add some more configuration to the threads like setAwaitTerminationSeconds(60); or setWaitForTasksToCompleteOnShutdown(true);?
What I found is, when using graceful.shutdown=enable and #PreDestroy in spring, that you need to synchronize the run() method and the #PreDestroy method (provided that both are in the same class):
#Service
public class MyClass implements Runnable {
private volatile boolean shutDown = false;
public MyClass( TaskScheduler taskScheduler) {
taskScheduler.scheduleWithFixedDelay(this, 100);
}
#PreDestroy
public synchronized void preDestroy() {
this.shutDown = true;
log.info("#PreDestroy Callback triggered for shutting down");
}
#Override
public synchronized void run() {
if (this.shutDown) {
this.shutdownCounter++;
return;
}
// put in here, whatever you long running task needs to do
}
And you need to make sure, that your run() method is not doing anything, when preDestroy() was already called, hence the shutdown- flag.
What the synchronize does is, that preDestroy() automatically waits until run() is finished regularly. Only then preDestroy() is called, and by setting the shutDown flag, it prevents that it starts another long running thread, even in case run() is called again. Instead run() returns immediately.
Because otherwise, when you don't synchronized, then the preDestroy() is called immediately after the spring - server get a shutdown signal but spring thinks if preDestroy() has run and finished successful, that it can shut down itself immediately. Which is not what you want, because then all run() threads gets interrupted.
I also found, that this example above does not work when using the #Scheduled- annotation (instead of calling taskScheduler.scheduleWithFixedDelay(this, 100) in the constructor)
Am building a spring boot rest api application deployed on weblogic 12c.
One of my requirement is to run some long running tasks on every incoming request.
An incoming rest request could result into multiple asynchronous task executions.
Since I dont care for the response and nor any exceptions that will result from these tasks I chose to use the ExecutorService and not Callable or CompletableFuture.
ExecutorService executorService =
Executors.newFixedThreadPool(2, new CustomizableThreadFactory("-abc-"));
Then for the incoming request that I receive in controller run two for loops and assign those tasks to the ExecutorService:
for (final String orderId : orderIds) {
for (final String itemId : itemIds) {
exec.execute(new Runnable() {
public void run() {
try {
//call database operation
}catch(Throwable t) {
logger.error("EXCEPTION with {} , {}" ,orderId,itemId
)
}
});
}//for
}//for
My question is regarding shutting down of the ExecutorService.
I am aware about graceful shutdown ( shutdown ) a hybrid shutdown ( awaitTermination ) or an abrupt shutdown ( shutdownNow )
what would be the preferred approach between the three for a rest api application ?
also is there any limit on how many thread pools can get created viz a viz as the number of ExecutorService thread pools getting created will be driven by the number of incoming requests
We currently have similar requirements, this is a difficult problem to solve as you want to use the right hammer if you will. There are very heavy weight solutions to orchestrating long running processes, for example SpringBatch.
Firstly though don't bother stop and starting the ExecutorService. The whole point of that class is to take the burden of Thread management off your hands, so you don't need to create and stop Threads yourself. So you don't need to manage the manager.
But be careful with your approach. Without using queues or another load balancing technique to smartly balance the long running processes across instances in your app. Or managing what happens when a Thread dies, you may get into a world of trouble. In general I would say nowadays it doesn't make much sense to interact directly with Threads or ThreadPools, and to use higher level solutions for this type of problem.
awaitTermination is usually a bit safer, while shutdownNow is more forceful. It's usually a good idea to use awaitTermination in a functional method, or even a runnable, if you would like the executor to shut down as soon as possible, but only after it has completed doing everything that it was created to do. In other words, when there are no active tasks that the executor is executing.
Ex.)
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors);
Observable.of(items).schedule(Schedulers.from(executor)).flatMap(item -> {
... // this block represents a task that the executor will execute in a worker thread
}).onSubscribe(onNext ->
logItem(onNext), throwable ->
throwable.printStackTrace(), /* onComplete */ () ->
executor.awaitTermination(60, TimeUnit.Seconds)
);
... // you need to shutdown asap because these other methods below are also doing some computation/io-intensive stuff
Now, when this method is finished, it will call awaitTermination, which will either close the pool immediately if it is not executing any tasks, or wait up to 60 seconds if tasks are still being executed.
Threads, or workers, will cease to be active for 60 seconds of inactivity in most cases, since that is usually the default.
On the other hand, if you want tasks to stop executing as soon as (to give some examples) an exception is thrown, there was a breach in security, or another module/service has failed, you might want to use shutdownNow() to stop all tasks immediately without the option of waiting.
My advice for choosing between the two would be to use shutdownNow in you catch block if you do not want tasks to continue to be executed if there is an exception - i.e., there is no longer a reason to return the list of items to the client given that one of the items did not get added to the list.
Otherwise, I'd recommend using awaitTermination after your try-catch, set to one minute, to safely shut down the thread pool as soon as it has executed all the tasks you have given it. But only do that if you know that the executor will not responsible for executing any more tasks down the line.
The simple shutdown, if that is an option for you, is also a good method. shutdown will reject all incoming tasks but wait until current tasks are finished executing, according to the Oracle docs.
If your not sure when you need to close the executor, it might be a good idea to use an #PreDestroy method so that the executor will just before the destroy method has been called on your bean:
#PreDestroy
private void cleanup(){
executor.shutdown();
}
I would like to override behaviour so that ExecutorService calls custom method. When a thread is released I would like to clear all ThreadLocal variables. Not very familiar with api or maybe there is something which exists there already.
Not sure how thread pool manages threads when they finished their job but I assume it does not destroy them as that would be expensive if it does not destroy them then based on ThreadLocal description:
Each thread holds an implicit reference to its copy of a thread-local
* variable as long as the thread is alive and the {#code ThreadLocal}
* instance is accessible; after a thread goes away, all of its copies of
* thread-local instances are subject to garbage collection (unless other
* references to these copies exist).
I need to clear up ThreadLocal
For an ExecutorService you could make a self cleaning task.
public CleanerTask implements Runnable {
private Disposable realRunnable;
public CleanerTask(Disposable d) {
realRunnable = d;
}
public void run() {
realRunnable.run();
realRunnable.dispose();
}
}
In this example Disposable is an interface extending Runnable and providing a dispose() method that cleans the ThreadLocal variables. The implementation guarantees that run() and dispose() are run in the same thread, so the variables can safely be cleared.
Then you just need to make sure you wrap your tasks in a CleanerTask before submitting them to your executor.
However if you're not tied to ExecutorService you can extend ThreadPoolExecutor which provides an afterExecute method. Then you just call dispose() there (after checking that the Runnable is of the correct type).
(I first thought afterExecute wasn't run in the thread that ran the task, but luckily I thought wrong.)
Not sure if you are thinking about threads and thread pools in a right way. Threads are started with start() and when their execution is finished, they are destroyed. How and when the threads are created depends on your executor service implementation... You might have executor service that just runs tasks in the current thread. Pooled executor service might start its threads with infinite loop waiting for submitted tasks... however even thread pools are usually flexible in a way that the pool keeps only a limited number of waiting threads and if there are more threads it lets them die (breaks the infinite sleep loop). Also usually if the execution throws an exception, the thread is discarded as well.
Having thread-locals survive a single execution is not a good practice. You should clean up your thread-locals after every execution. Do not wait for thread disposal / destruction.
TL;DR Do not try to hack into "thread destruction", but rather start every execution with try/finally to set-up and clean your thread locals.
Threads will get reused by an executorservice that implements a threadpool, those threadlocal entries will stay with the thread across tasks unless removed. If you know when a task is done that its Threadlocal value is now irrelevant, you can clean it up like Kayaman says.
But the point of Threadlocals is that they are available across different components, for cases where the different components can't manage its scope. For instance a web application could put something in a threadlocal in a filter on the way in with a HTTP request, have it available to web controllers and services, etc., over the course of the request, and clean up the threadlocal in the filter on the way back out. So in this example the scope of the threadlocal value is managed by the filter in order to be available to everything participating in the request for that thread, where in a "normal" (meaning not some async non-blocking setup like Play) web application the request is handled by one thread in the application server.
If it's that straightforward for you to identify the scope where the ThreadLocal value isn't needed anymore that the task can clean it up, then it sounds like your code is using ThreadLocals unnecessarily. I'd suggest removing these ThreadLocals and using local variables within the task instead. A ThreadLocal shouldn't be used as an easy alternative to argument-passing.
is there any kind of Runnable, Callable or Thread with capability of stopping it in any duration of time?
I wrote something like this
public class ThreadRunner {
private ExecutorService threadPoolExecutor;
ThreadRunner() {
threadPoolExecutor = Executors.newSingleThreadExecutor();
}
public void startThread(String endPoint, ProgressBar progressBar) {
Runnable task = () -> {
// some code which saves images from URL (1230 images) and updates progress bar
};
threadPoolExecutor.execute(task);
}
public void stopThread() {
threadPoolExecutor.shutdownNow();
}
}
Thread runs correctly, images are being saved, progress bar being updated, but when I want to stop thread (or maybe even pause process of saving if possible) by calling ThreadRunner class's method - nothing happens.
Am I doing something wrong - or most likely - what am I doing wrong?
is there any kind of Runnable, Callable or Thread with capability of stopping it in any duration of time?
You can implement such a thing yourself, but there is no generic support available for it, unless you count the long-deprecated Thread.stop() methods. Under no circumstances should you use those methods, but do read their API docs for a discussion of why they are deprecated and what you can do instead. You can find a longer-form version of the discussion in Java's technical notes.
The bottom line is that the computation you want to be able to stop needs to periodically check some shared variable or built-in condition to determine whether to do so. You arrange for that variable to be set when you want the thread to stop, and if you need to block until it does stop then you join() it. Under some circumstances, it can be helpful to interrupt() the thread to get it to check the variable (or being interrupted can itself serve as the termination condition). The user-facing end of this can be wrapped up in a method.
In any case, an ExecutorService cannot give you a handle on this. Requesting such a service to shut down will prevent it from dispatching any more tasks, but there is no safe, general-purpose mechanism by which it could force a premature shutdown of tasks that are already running.
Once started, a thread will run until Runnable.run() exits. Due to several issues you should never use Thread.stop() or Thread.interrupt().
Instead, you will have to implement your own logic for exit/pause. A few suggestions:
For stopping the thread, you can make a boolean variable shouldExit. In your thread, check this variable every now and then, and just do "return" or break the for/while loop when it becomes true. Setting this variable from another thread should now make the downloader exit. If necessary, you should surround access to this variable with synchronized block as to prevent any race conditions.
For pausing the thread, you can use a similar approach. When you set a certain variable to true (e.g. isPaused), make the thread react by going into an Object.sleep(). This way, it won't consume any CPU during sleep. You can then use Object.notify() from another thread to "kick" the sleeping thread out ouf sleep. You will need a synchronized block here, too.
I have a process that I want to be triggered by different sources.
Let's say we have one case where we habe some other process (let's call it "manualStarter") under certain conditions wants to trigger this main process. The main process takes a while to complete, let's say 10 seconds to 10 minutes. In case the process is already in progress while the manualStarter is trying to start it, it should not be queued more than once. The second process to trigger the start of the main process could be a "timedStarter" which would trigger the process once in a while, but only if the process is not running, else it would not queue the process to be triggered, instead would try it again some time later.
Now I've tried implementing this kind of process manager by using the isAlive() and join(), but it seems isAlive() is not reliable at all, until it changes its state to alive, 100 threads of this thread might get started (and do sometimes). So seems I couldn't rely on that.
Then I tried using the SingleThreadExecutor service which is closer to what I'm looking for, it's not blocking anything and it only allows a single thread to execute the process, so that's good, however I still don't know how to check the status/lock it properly, or how else I can ensure that the queue for starting the thread doesn't become larger than 1. I read a bit that semaphores are often used for similar kinds of tasks, but I am not sure how I could use them in this scenario.
So how could I achieve what I want? Do I need to implement my own ThreadPoolExecutor? How can I do it? Is there any better way?
Just use a shared flag so the manual starter knows if the thread is running. For example:
// Schedule this to run periodically via ScheduledExecutorService
class ManualStarter {
private final AtomicBoolen isRunning = new AtomicBoolean(false);
private ExecutorService exec = Executors.newSingleThreadedExecutor();
public void run() {
if (!isRunning.getAndSet(true)) {
// It wasn't running so this will start it
exec.submit(new MainProcess(isRunning));
}
}
}
class MainProcess extends Runnable {
private final AtomicBoolean isRunning;
MainProcess(AtomicBoolean isRunning) { this.isRunning = isRunning; }
#Override
public void run() {
// do whatever it does
isRunning.set(false);
}
}
Then somewhere you schedule the main thing to run periodically doing something like:
ScheduledExectorService sched = Executors.newScheduledThreadPool(1);
ManualStarter starter = new ManualStarter();
// Every 10 seconds will check if MainProcess is running and will start
// it if it's not
sched..scheduleAtFixedRate(starter, 0, 10, SECONDS);
You should rather use ExecutorService for that. There is couple of implementations available (including ScheduledExecutorService that allows you to schedule deffered and/or repeating tasks - check Executors). Just pick one that fits your needst the best.
As for conditional execution the task is simple. Define some sort of accessible flag that holds the current "state" of given task. If it is running - do nothing, if it is not running - schedule execution.
Simple example:
//our flag
private volatile AtomicBoolean isRunning=new AtomicBoolean(false);
public void scheduleTask(){
if(isRunning.get()){
return; // do nothing
}else{
synchronized(isRunning){
if(isRunning.get()){
return;
}else{
isRunning.set(true)
scheduleNewTask();
}
}
}
}
For any how-tos check the official Oracle's documentaion about Executors.
I have use AtomicBoolean in this example to mock "mutable" boolean. This can be done with boolean as well but synchronization needs to be done on different object (eg. dedicated private Object lock=new Object();)