Java Executor and Long-lived Threads - java

I've inherited some code that uses Executors.newFixedThreadPool(4); to run the 4 long-lived threads that do all the work of the application.
Is this recommended? I've read the Java Concurrency in Practice book and there does not seem to be much guidance around how to manage long-lived application threads.
What is the recommended way to start and manage several threads that each live for the entire live of the application?

You mentioned that code is using Executors, it should be returning an ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
ExecutorService is an Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.
As long as returned ExecutorService is performing graceful shutdown there should not be an issue.
You can check that your code is doing shutodwn by finding following in your code:
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
executor.awaitTermination();
Cheers !!

I assume that your long-lived thread do some periodic job in a loop. What you can do is the following:
Make sure that each runnable in the pool checks the pool's state before looping.
while( ! pool.isShutdown() ) { ... }
Your runnable must thus have a reference to their parent pool.
Install a JVM shutdown hook with Runtime.addShutdownHook(). The hook calls pool.shutdown() then pool.awaitTermination(). The pool will transition to the SHUTDOWN state and eventually the threads will stop, after which it will transition to the TERMINATED state.
--
That said, I'm a bit suspicious of your 4 threads. Shouldn't there be only 1 long-live threads, which fetches tasks, and submits them to an executor service? Do you really have 4 different long-lived processes? (This consideration is orthogonal to the main question).

Related

Short but frequent jobs: HandlerThread or ThreadPoolExecutor?

First of all, I could not determine what the title should be, so if it's not specific enough, the question itself will be.
We have an application that uses a foreground service and stays alive forever, and in this service, there are frequent database access jobs, network access jobs and some more, that needs to run on background threads. One job itself consumes a small amount of time, but the jobs themselves are frequent. Obviously, they need to run on worker threads, so I'm here to ask which design we should follow.
HandlerThread is a structure that creates a singular thread and uses a queue to execute tasks but always loops and waits for messages which consumes power, while ThreadPoolExecutor creates multiple threads for each job and deletes threads when the jobs are done, but because of too many threads there could be leaks, or out-of-memory even. The job count may be 5, or it may be 20, depending on how the user acts in a certain way. And, between 2 jobs, there can be a 5 second gap, or a day gap, totally depending on user. But, remember, the application stays alive forever and waits for these jobs to execute.
So, for this specific occasion, which one is better to use? A thread pool executor or a handler thread? Any advice is appreciated, thanks.
Caveat: I do not do Android work, so I am no expert there. My opinions here are based a quick reading of Android documentation.
tl;dr
➥ Use Executors rather than HandlerThread.
The Executors framework is more modern, flexible, and powerful than the legacy Thread facility used by HandlerThread. Everything you can do in HandlerThread you can do better with executors.
Differences
One big difference between HandlerThread and ThreadPoolExecutor is that the first comes from Android while the second comes from Java. So if you'll be doing other work with Java, you might not want to get in the habit of using HandlerThread.
Another big difference is age. The android.os.HandlerThread class inherits from java.lang.Thread, and dates back to the original Android API level 1. While nice for its time, the Thread facility in Java is limited in its design. That facility was supplanted by the more modern, flexible, and powerful Executors framework in later Java.
Executors
Your Question is not clear about whether these are recurring jobs or sporadically scheduled. Either can be handled with Executors.
For jobs that run once at a specific time, and for recurring scheduled jobs, use a ScheduledExecutorService. You can schedule a job to run once at a certain time by specifying a delay, a span of time to wait until execution. For repeated jobs, you can specify an amount to wait, then run, then wait, then run, and so on. I'll not address this further, as you seem to be talking about sporadic immediate jobs rather than scheduled or repeating jobs. If interested, search Stack Overflow as ScheduledExecutorService has been covered many times already on Stack Overflow.
Single thread pool
HandlerThread is a structure that creates a singular thread
If you want to recreate that single thread behavior, use a thread pool consisting of only a single thread.
ExecutorService es = Executors.newSingleThreadExecutor() ;
Make your tasks. Implement either Runnable or Callable using (a) a class implementing either interface, (b) without defining a class, via lambda syntax or conventional syntax.
Conventional syntax.
Runnable sayHelloJob = new Runnable()
{
#Override
public void run ( )
{
System.out.println( "Hello. " + Instant.now() );
}
};
Lambda syntax.
Runnable sayBonjourJob = ( ) -> System.out.println( "Bonjour. " + Instant.now() );
Submit as many of these jobs to the executor service as you wish.
es.submit( sayHelloJob ) ;
es.submit( sayBonjourJob ) ;
Notice that the submit method returns a Future. With that Future object, you can check if the computation is complete, wait for its completion, or retrieve the result of the computation. Or you may choose to ignore the Future object as seen in the code above.
Fixed thread pool
If you want multiple thread behavior, just create your executor with a different kind of thread pool.
A fixed thread pool has a maximum number of threads servicing a single queue of submitted jobs (Runnable or Callable objects). The threads continue to live, and are replaced as needed in case of failure.
ExecutorService es = Executors.newFixedThreadPool​( 3 ) ; // Specify number of threads.
The rest of the code remains the same. That is the beauty of using the ExecutorService interface: You can change the implementation of the executor service to get difference behavior while not breaking your code that calls upon that executor service.
Cached thread pool
Your needs may be better service by a cached thread pool. Rather than immediately creating and maintaining a certain number of threads as the fixed thread pool does, this pool creates threads only as needed, up to a maximum. When a thread is done, and resting for over a minute, the thread is terminated. As the Javadoc notes, this is ideal for “many short-lived asynchronous tasks” such as yours. But notice that there is no upper limit of threads that may be running simultaneously. If the nature of your app is such that you may see often spikes of many jobs arriving simultaneously, you may want to use a different implementation other than cached thread pool.
ExecutorService es = Executors.newCachedThreadPool() ;
Managing executors and threads
but because of too many threads there could be leaks, or out-of-memory even
It is the job of you the programmer and your sysadmin to not overburden the production server. You need to monitor performance in production. The managagement is easy enough to perform, as you control the number of threads available in the thread pool backing your executor service.
We have an application that uses a foreground service and stays alive forever
Of course your app does eventually come to end, being shutdown. When that happens, be sure to shutdown your executor and its backing thread pool. Otherwise the threads may survive, and continue indefinitely. Be sure to use the life cycle hooks of your app’s execution environment to detect and react to the app shutting down.
The job count may be 5, or it may be 20, depending on how the user acts in a certain way.
Jobs submitted to an executor service are buffered up until they can be scheduled on a thread for execution. So you may have a thread pool of, for example, 3 threads and 20 waiting jobs. No problem. The waiting jobs will be eventually executed when their time comes.
You may want to prioritize certain jobs, to be done ahead of lower priority jobs. One easy way to do this is to have two executor services. Each executor has its own backing thread pool. One executor is for the fewer but higher-priority jobs, while the other executor is for the many lower-priority jobs.
Remember that threads in a thread pool doing no work, on stand-by, have virtually no overhead in Java for either CPU or memory. So there is no downside to having a special higher-priority executor service sitting around and waiting for eventual jobs to arrive. The only concern is that your total number of all background threads and their workload not overwhelm your machine. Also, the implementation of the thread pool may well shut down unused threads after a period of disuse.
Don't really think its a question of the number of threads you are running, more how you want them run. If you want them run one at at time (i.e. you only want to execute on database query at a time) then use a HandlerThread. If you want multi-threading / a pool of threads, then use and Executor.
In my experience, leaks are really more down to how you have coded your threads, not really the chosen implementation.
Personally, I'd use a HandlerThread, here's a nice article on implementing them and how to avoid memory leaks ... Using HandlerThread in Android

A couple of questions regarding Java ExecutorService newFixedThreadPool

Please note that I usually ask a question after googling for more than 20 times about the issue. But I can't still understand it. So I need your help.
Basically, I don't understand the exact usage of newFixedThreadPool
Does newFixedThreadPool(10) mean having ten different threads? Or does it mean it can have 10 of the same threads? or the both?
I executed with submit() methods more than 20 times and it's working.
Does submit() print a value? Or are you putting threads in the ExecutorService?
Briefly, tasks are small units of code that could be executed in parallel (code sections). The threads (in a thread pool) are what execute them. You can think of the threads like workers and the tasks like jobs. Jobs can be done in parallel, and workers can work in parallel. Workers work on jobs.
So, to answer your questions:
newFixedThreadPool(int nThreads) creates a thread pool of nThread threads that operate on the same input queue. nThreads is the maximum number of threads that can be running at any given time. Each thread can run a different task. With your example, you can be running up to 10 tasks at the same time. (The documentation can be found here with credit to #hovercraft-full-of-eels)
submit() pushes the given task into an event queue that is shared by the threads in the thread pool. Once a thread is available, it will take a task from the front of the queue and execute it. It shouldn't print anything, unless the Runnable you pass it has a print statement in it. However, the print statement may not be printed right when you submit the task! It will print once a thread is executing that particular task. (The documentation can be found here)
Just refer java docs or JAVA API's description rather than googling it.
For your questions I have below comments .
Question 1 ->
ExecutorService executorService = Executors.newFixedThreadPool(10);
First an ExecutorService is created using the Executors newFixedThreadPool() factory method. This creates a thread pool with 10 threads executing tasks.
Executors.newFixedThreadPool API creates, a thread pool that reuses a fixed number of threads and these threads work on a s***hared unbounded queue***.
At any point, at most nThreads threads will be active processing tasks.
If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available.
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly SHUTDOWN.
After submitting even 20 tasks ,it worked with this thread pool.
Internally it calls below line of codes .
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
Question 2- > Submits a Runnable task for execution in Queue and it can also return an Object of type Future Object representing task. we can use Future's get method to check whether submitted task has successfully completed or not because it will return null upon successful completion.

Maintaining a single executor service and shutting it down appropriately

My application requires that a certain job be done asynchronously, so I've resorted to the executor framework. This job (a Runnable) is expected to be run should a certain external interface be down (the vendor could be backed up for a while, say, 30 mins).
With this ask in mind, I believe I should maintain a single scheduled executor service with a fixed no. of core threads that perform these jobs when the interface I said above goes down for a brief moment (as a static variable in the class I need the thread pool in). I also don't think I should create an executor for every need to handle such a job (single scheduled thread pool executor), and shut down after a job is run, because that would defeat my purpose, wouldn't it? Because that could mean reserving a thread for every job during the backed up hour which sounds scary to me.
But, if I were to maintain such a single executor service, when would I be shutting down the executor? I understand that an executor once shut down can't be reused, while not shutting down the executor and keeping threads active could prevent the JVM from shutting down. How do I go about this?
My last statement was based on this from Effective Java 2nd edition:
And here is how to tell the executor to terminate gracefully (if you
fail to do this, it is likely that your VM will not exit):
executor.shutdown();
This job (a Runnable) is expected to be run should a certain external
interface be down (the vendor could be backed up for a while, say, 30
mins).
Above is your requirement. Now the solution entirely depends on how above situation is handled.
Trigger or event listener: If you have some trigger or event listener which can be called when it is found that a certain external interface is down, then in the that triggered code or event listener, you can create a ExecutorService, execute all your tasks (you can choose on fixed or pooled thread pool), and then on completion of all tasks, you can shutdown the ExecutorService
In this case, it is a good idea to create a ExecutorService, do tasks and shut it down. No need of long running ExecutorService.
Track or periodic check: If you have to track or check periodically whether certain external interface is down or not, then I think you can have a ScheduledThreadPoolExecutor implementation to have check after fixed time interval whether certain external interface is down or not, and if it is down then execute all your tasks. In this case you will NOT shutdown your ExecutorService and it will always be running.
Check scheduleAtFixedRate and scheduleWithFixedDelay for periodic task scheduling.
P.S.: Trigger and Track are my own convention I used tangentially as one word, so do infer it in technical words.
I understand that an executor once shut down can't be reused, while
not shutting down the executor and keeping threads active could
prevent the JVM from shutting down.
Yes, an executor once shut down can't be reused.
No, a running ExecutorService will not stop you JVM shutdown, but once JVM is shutdown that ExecutorService instance and its thread pool will be stopped and destroyed.

Java concurrency – Immediate thread pool shutdown

I am creating thread pools like this:
ExecutorService workers = Executors.newCachedThreadPool();
Invoking each pool tasks like this:
workers.invokeAll(tasks);
And after completion shutting those down like this:
workers.shutdown();
I have about 4 thread pools that do different procedures and those thread pools are being created from a servlet class.
What I want to do is shutdown all threads in those thread pools.
What is the cleanest way to achieve this?
Thanks
If all your worker tasks handle interrupts properly you could try to invoke:
workers.shutdownNow()
That call with typically send interrupts too all worker threads. However, proper interrupt handling is a bit implicit and the method documentation says that only a best effort attempt to stop the tasks is made. Hence, some JVM implementations might make a worse attempt than sending interrupts, why you might not want to trust this call.
You might want to look into other answers how to gracefully ensure proper shutdown of threads and implement such a solution for all your worker tasks, to guarantee proper shutdown. For example, in this answer, Jack explains the typical solution to have a volatile field that you can check in your workers. This field can be set from where you want to stop your tasks.

How to reset a thread pool efficiently

I'm using a thread pool to enable multiple unimportant tasks to be queued and (potentially) executed however I need to be able to easily cancel all queued and executing tasks and start a new queue from scratch.
ie:
// startup
pool = Executors.newFixedThreadPool(5);
// reset
pool.shutdownNow();
pool = Executors.newFixedThreadPool(5);
The implementation I'm using now seems to work but I'm not sure that shutting down completely and creating a new thread pool is particularly efficient.
The reset happens regularly, in some usages it happens just as regularly as scheduling a task! Since there is no way to determine if any tasks are awaiting execution (or is there?) I feel I am shutting down the pool way too often.
Is there a more suitable pool implementation or a better way to achieve this functionality?
EDIT: solution
I'm now running with:
// startup
pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
// reset
for (Future<?> task : pool.getQueue().toArray(new Future[0]))
task.cancel(true);
I've ignored the call to 'purge' because this is slow and the queue will be tidied up later by the pool anyway. I am aware that currently executing tasks may not be terminated by this and that works for me.
thanks.
You could monitor all of the Futures you get from submitting the tasks and cancel() all of them which would allow you to re-use the thread-pool without recreated. However, I doubt that you would gain too much extra efficiency.
As long as you aren't doing this too often, I think your mechanism should work fine. One thing to realize is that although you are calling pool.shutdownNow(), this will only interrupt the running jobs which won't necessarily stop them. It depends on what they are doing and whether they are executing methods that throw InterruptedException often or listening to the thread interrupt flag. So even if shutdownNow() returns, some of the tasks may still be executing.
You can cancel all pending (and, probably running) tasks:
for (Future f: pool.getQueue().toArray(new Future[0]))
{
f.cancel(true); // or false
}
pool.purge();

Categories

Resources