Executor Service shutdown - java

I am using the ExecutorService. I am opening 10 threads for a for-loop. So it opens 10 threads and when does the connection closes here? At executor.shutdown()? If yes, will it closes all 10 threads and open 10 threads again? Is there anything I can follow better coding standards in order to increase the performance here?
ExecutorService executor = Executors.newFixedThreadPool(10);
for(String str : stringList){
for(String str1 : stringList1){
for(String str2 : stringList2){
executor.execute(new Runnable() {
#Override
public void run() {
//do something
}
}
}
}
executor.shutdown();
executor.awaitTermination(24L, TimeUnit.HOURS);
Actually my idea is to iterate through the loop and save the data in a file and save it for every iteration. So I want to follow the best practices here as I don't want to see any server related issues like connection issues/outOfMemory exceptions in later stages. Please suggest.
I have implemented this by myself but I am a noob in multi-threading. So to get some clarification after seeing some other blogs and posts I have posted this. Please help!

Executors.newFixedThreadPool(10) does exactly what it sounds like - it creates a thread pool, with a maximum of 10 threads. From the documentation:
The threads in the pool will exist until it is explicitly shutdown
So, best practice is to share the thread pool where possible. Don't do this:
for (int i = 0; i < 8; i++) {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (String str1 : stringList1) {
for (String str1 : stringList1) {
executor.execute(new Runnable(){
public void run(){ /* Some work... */ }
});
}
}
executor.shutdown();
executor.awaitTermination(24L, TimeUnit.HOURS);
}
Notice that a new FixedThreadPool is created and destroyed 8 times within the for-loop, and creating/destroying the thread pools is creating/destroying up to 10 threads. This is bad, because it defeats the point of using a thread pool. If you're going to use a pool within a loop, make sure you re-use it where you can:
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 8; i++) {
for (String str1 : stringList1) {
for (String str1 : stringList1) {
executor.execute(new Runnable(){
public void run(){ /* Some work... */ }
});
}
}
}
executor.shutdown();
executor.awaitTermination(24L, TimeUnit.HOURS);
And finally, one last thing to watch out for is the amount of work you queue. If you are queueing work faster than the thread pool can process it, then the queue size will slowly grow, until you reach an OutOfMemoryException. Unfortunately, there's no built-in way to check the number of tasks remaining in the thread pool, so you'll have to work that one out on your own.
This concept applies to the server as well - if the number of incoming requests per second is higher than the number of requests the server can process per second, for a long enough duration, then the server will run out of resources and crash. The solution is usually to have automatic scaling and load balancing, and knowing how to configure these things is a very useful skill to have in the industry.

when does the connection closes here? At executor.shutdown()? If yes, will it closes all 10 threads and open 10 threads again?
Once you call ExecutorService.html#shutdown, no new new tasks are submitted to the pool and once no tasks in the pool, ExecutorService will be shutdown.
void 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.
Once shutdown is triggered, it won't open 10 threads again unless you re-create ExecutorService
Actually my idea is to iterate through the loop and save the data in a file and save it for every iteration. So I want to follow the best practices here as I don't want to see any server related issues like connection issues/outOfMemory exceptions in later stages
Don't do it. Let's wait for ExecutorService to properly shutdown.
Other way to address your issue : Wait for completion of your tasks. You can find more details in:
How to properly shutdown java ExecutorService
On a different note:
newFixedThreadPool creates unbounded ExecutorService. Look out for other alternatives in:
How to properly use Java Executor?

Related

Is it possible to wait the main thread while all the threads of executor service are processing tasks

I am having a scenario of around inserting millions of data into the back end and currently using executor framework to load this. I will explain my problem in simpler terms.
In the below case, I am having 10 runnable and three threads to execute the same. Consider my runnable is doing an insert operation and it is taking time to complete the task. When I checked ,It is understood that ,if all the threads are busy, the other tasks will go to the queue and once the threads completed the tasks ,it will fetch the tasks from the pool and complete it.
So in this case, object of SampleRunnable 4 to 10 will be created and this will be in the pool.
Problem: Since I need to load millions of tasks,I cannot load all the records in queue which can lead to memory issues. So my question is instead of taking all tasks in the queue ,is it possible to make the main thread waiting until any one of the executor worker threads becomes available.
Following approaches I tried as a work around instead of queuing this much tasks:
Approach 1: Used Array Blocking Queue for executor and gave the size as 5 (for e.g.)
So in this case, when the 9th task comes ,this will throw RejectedExecutionException and in the catch clause,put a sleep for 1 minute and recursively trying the same.This will get picked up on any of the retry when the thread is available.
Approach 2: Used shut down and await termination. i.e. if the task count is 5, i am putting shut down and await termination. In the await Termination 'if' block (executor.awaitTermination(60000,TimeUnit.SECONDS)),I am instantiating the thread pool again.
public class SampleMain {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i=0;i<10;i++){
executorService.execute(new SampleRunnable(i));
}
executor.shutdown();
}
Sounds like the problem is, you want to throttle the main thread, so that it does not get ahead of the workers. If that's the case, then consider explicitly constructing a ThreadPoolExecutor instance instead of calling Executors.newFixedThreadPool().
That class has several different constructors, and most of them allow you to supply your own blocking queue. If you create an ArrayBlockingQueue with a limited size, then every time the queue becomes full, the main thread will be automatically blocked until a worker makes room by taking another task.
final int work_queue_size = 30;
BlockingQueue work_queue = new ArrayBlockingQueue(work_queue_size);
ExecutorService executor = new ThreadPoolExecutor(..., work_queue);
for (int i=0;i<10;i++){
executorService.execute(new SampleRunnable(i));
}
...

Why does ForkJoinPool.commonPool().execute(runnable) take more time to run the thread

I am using ForkJoinPool.commonPool().execute(runnable) as a handy way to spawn a thread in many places across my application. But at a particular invocation of that it is taking more time (more than 10 seconds) to invoke the code in the runnable in a thread. What could be the reason for that? How to avoid that?
EDIT: As per #ben 's answer, avoiding long running process in thread pool seems to the solution. Creating new thread manually solved my problem instead of using common ForkJoinPool.
So after some quick testing I found the issue. Look at the following example code:
List<Runnable> runnables = new ArrayList<Runnable>();
for (int i = 0; i < 20; ++i)
{
runnables.add(() -> {
System.out.println("Runnable start");
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
}
System.out.println("Runnable end");
});
}
for (Runnable run : runnables)
{
//ForkJoinPool.commonPool().execute(run);
//new Thread(run).start();
}
Comment in one of the two lines.
We create a number of runnables that send a message, sit idle for 10s and send a message again. Quite simple.
When using Threads for each of those all Runnables send Runnable start 10s pass, all runnables send Runnable end.
When using the commonPool() just a number of them sends Runnable start 10s pass, they send Runnable end and another bunch of them sends Runnable start until they are all finished.
This is simply because the number of cores on your system determines how many threads the threadpool will hold. When all of them are filled new tasks are not executed until one thread is freed up.
So moral of the story: Only use a threadpool when you know the way it works internally and that is what you want it to do.

Thread Scheduling - Run threads in set order

I have a set of roughly 20 threads and i want to schedule them so they run in a set order.
Is there a way to do this. I have tried using priority and setting the priority 1-10 but the scheduler still seems to execute threads at its own order. Btw im working in Java
Is there a way to run threads in a set order ?
Thanks
regards
Mike
What you need is an ExecutorService that will run your threads one at a time, namely : newSingleThreadExecutor.
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.submit(job1);
pool.submit(job2);
pool.submit(job3);
Why do you have multiple threads if you want synchronous behaviour in the first place?
If you've acquired multiple Thread objects from "something else" then you can use thread.run() to execute them in the current thread, which will, of course allow you to control the order.
You don't have to run a single threaded version if the jobs can be executed in parallel. Below is an example where you can use eight threads to run your 20 jobs:
public static void main(String[] args) {
final ExecutorService executorService = Executors.newFixedThreadPool(8);
final Queue<Integer> workItems = new ConcurrentLinkedQueue<Integer>();
for (int i = 0; i < 20; i++) {
workItems.add(i);
}
for (int i = 0; i < 20; i++) {
executorService.submit(new Runnable() {
#Override
public void run() {
final Integer workIem = workItems.poll();
// process work item
}
});
}
// await termination of the exec service using shutdown() and awaitTermination()
}
The idea is that you use an auxiliary queue to maintain the items to be processed and rely on the FIFO ordering of the queue to process the items in order and in parallel.
If the threads depend on each other, then one option would be to schedule only the first thread and have it spawn its dependent threads, which can then turn their dependent threads, etc...
You need to understand, however, that even though you may be launching threads in a particular order, as soon as they start they are off of your hands and they will be fighting for resources and the OS will time-slice their executions, which means some may get "ahead" of threads that were launched before. So if you truly need to keep the order, then I would suggest you use only one thread and let it orchestrate the tasks in a synchronized manner.

How to schedule a group of threads (tasks) at variable times?

I have to launch 10 tasks asynchronously at variable times through out the day until a certain hour the next day. The closer I get to the time the next day the more I have to repeat these 10 tasks.
My question, is how should I manage this? What executors should I use? What is the best way to manage the memory?
I thought of using an Executors.newScheduledThreadPool that could start a threadpool process with the 10 tasks at variable times. The problem requires me to launch a new set of tasks even though the previous group of tasks have not finished (so probably trigger a new threadpool each time).
I am also thinking of using sort of process registry to manage the different processes that have been launched. When a process is unused anymore than the registry can stop it.
And each time the tasks are done, I thought of flushing the runnables, and stopping the threadpool. Is that overall a good solution?
The problem that may arise, is to have the memory saturated with threadpools. Maybe put a time limit on the threadpool?
I guess, you need one dispatching thread inside plain non-scheduling pool and another pool for workers, something like this:
ExecutorService ex = Executors.newFixedThreadPool(1);
final ExecutorService workersPool = Executors.newCachedThreadPool();
ex.submit(new Runnable() {
public void run() {
try {
do {
// determine if it's time to start workers
if (timeToStartWorkers()) {
workersPool.submit(new Worker(...));
workersPool.submit(new Worker(...));
...
}
// sleep till next time
Thread.sleep(timeTillNextCheck);
}
} catch (InterruptedException e) {
// handle exception
}
}
});
No need to recreate thread pools.

500 Worker Threads, what kind of thread pool?

I am wondering if this is the best way to do this. I have about 500 threads that run indefinitely, but Thread.sleep for a minute when done one cycle of processing.
ExecutorService es = Executors.newFixedThreadPool(list.size()+1);
for (int i = 0; i < list.size(); i++) {
es.execute(coreAppVector.elementAt(i)); //coreAppVector is a vector of extends thread objects
}
The code that is executing is really simple and basically just this
class aThread extends Thread {
public void run(){
while(true){
Thread.sleep(ONE_MINUTE);
//Lots of computation every minute
}
}
}
I do need a separate threads for each running task, so changing the architecture isn't an option. I tried making my threadPool size equal to Runtime.getRuntime().availableProcessors() which attempted to run all 500 threads, but only let 8 (4xhyperthreading) of them execute. The other threads wouldn't surrender and let other threads have their turn. I tried putting in a wait() and notify(), but still no luck. If anyone has a simple example or some tips, I would be grateful!
Well, the design is arguably flawed. The threads implement Genetic-Programming or GP, a type of learning algorithm. Each thread analyzes advanced trends makes predictions. If the thread ever completes, the learning is lost. That said, I was hoping that sleep() would allow me to share some of the resources while one thread isn't "learning"
So the actual requirements are
how can I schedule tasks that maintain
state and run every 2 minutes, but
control how many execute at one time.
If your threads are not terminating, this is the fault of the code within the thread, not the thread pool. For more detailed help you will need to post the code that is being executed.
Also, why do you put each Thread to sleep when it is done; wouldn't it be better just to let it complete?
Additionally, I think you are misusing the thread pool by having a number of threads equal to the number of tasks you wish to execute. The point of a thread pool is to put a constraint on the number of resources used; this approach is no better than not using a thread pool at all.
Finally, you don't need to pass instances of Thread to your ExecutorService, just instances of Runnable. ExecutorService maintains its own pool of threads which loop indefinitely, pulling work off of an internal queue (the work being the Runnables you submit).
Why not used a ScheduledExecutorService to schedule each task to run once per minute, instead of leaving all these threads idle for a full minute?
ScheduledExecutorService workers =
Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
for (Runnable task : list) {
workers.scheduleWithFixedDelay(task, 0, 1, TimeUnit.MINUTES);
}
What do you mean by, "changing the architecture isn't an option"? If you mean that you can't modify your task at all (specifically, the tasks have to loop, instead of running once, and the call to Thread.sleep() can't be removed), then "good performance isn't an option," either.
I'm not sure your code is semantically correct in how it's using a thread pool. ExecutionService creates and manages threads internally, a client should just supply an instance of Runnable, whose run() method will be executed in context of one of pooled threads. You can check my example. Also note that each running thread takes ~10Mb of system memory for the stack, and on linux the mapping of java-to-native threads is 1-to-1.
Instead of putting a tread to sleep you should let it return and use a ThreadPoolexecutor to execute work posted every minute to your work queue.
To answer your question, what type of thread pool?
I posted my comments but this really should address your issue. You have a computation that can take 2 seconds to complete. You have many tasks (500) that you want to be completed as fast as possible. The fastest possible throughput you can achieve, assuming there is no IO and or network traffic, is with Runtime.getRuntime().availableProcessors() number of threads.
If you increase your number to 500 threads, then each task will be executing on its own thread, but the OS will schedule a thread out every so often to give to another thread. Thats 125 context switches at any given point. Each context switch will increase the amount of time for each task to run.
The big picture here is that adding more threads does NOT equal greater throughput when you are way over the number of processors.
Edit: A quick update. You dont need to sleep here. When you execute the 500 tasks with 8 processors, each task will complete in the 2 seconds, finish and the thread it was running on will then take the next task and complete that one.
8 Threads is the max that your system can handle, any more and you are slowing yourself down with context switching.
Look at this article http://www.informit.com/articles/article.aspx?p=1339471&seqNum=4 It will give you an overview of how to do it.
This should do what you desire, but not what you asked for :-) You have to take out the Thread.sleep()
ScheduledRunnable.java
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledRunnable
{
public static void main(final String[] args)
{
final int numTasks = 10;
final ScheduledExecutorService ses = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
for (int i = 0; i < numTasks; i++)
{
ses.scheduleAtFixedRate(new MyRunnable(i), 0, 10, TimeUnit.SECONDS);
}
}
private static class MyRunnable implements Runnable
{
private int id;
private int numRuns;
private MyRunnable(final int id)
{
this.id = id;
this.numRuns = 0;
}
#Override
public void run()
{
this.numRuns += 1;
System.out.format("%d - %d\n", this.id, this.numRuns);
}
}
}
This schedules the Runnables every 10 SECONDS to show the behavior.
If you really need to wait a fixed amount of time AFTER processing is complete you might need to play around with which .scheduleXXX method that you need. I think fixedWait will just run it every N amount of time regardless of what the execution time is.
I do need a separate threads for each running task, so changing the architecture isn't an option.
If that is true (for example, making a call to an external blocking function), then create separate threads for them and start them. You can't create a thread pool with a limited number of threads, as a blocking function in one of threads will prevent any other runnable being put into it, and don't gain much creating a thread pool with one thread per task.
I tried making my threadPool size equal to Runtime.getRuntime().availableProcessors() which attempted to run all 500 threads, but only let 8 (4xhyperthreading) of them execute.
When you pass the Thread objects you are creating to thread pool, it only sees that they implement Runnable. Therefore it will run each Runnable to completion. Any loop which stops the run() method returning will not allow the next enqueued task to run; eg:
public static void main (String...args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
for (int i = 0; i < 10; ++i) {
final int task = i;
executor.execute(new Runnable () {
private long lastRunTime = 0;
#Override
public void run () {
for (int iteration = 0; iteration < 4; )
{
if (System.currentTimeMillis() - this.lastRunTime > TIME_OUT)
{
// do your work here
++iteration;
System.out.printf("Task {%d} iteration {%d} thread {%s}.\n", task, iteration, Thread.currentThread());
this.lastRunTime = System.currentTimeMillis();
}
else
{
Thread.yield(); // otherwise, let other threads run
}
}
}
});
}
executor.shutdown();
}
prints out:
Task {0} iteration {1} thread {Thread[pool-1-thread-1,5,main]}.
Task {1} iteration {1} thread {Thread[pool-1-thread-2,5,main]}.
Task {0} iteration {2} thread {Thread[pool-1-thread-1,5,main]}.
Task {1} iteration {2} thread {Thread[pool-1-thread-2,5,main]}.
Task {0} iteration {3} thread {Thread[pool-1-thread-1,5,main]}.
Task {1} iteration {3} thread {Thread[pool-1-thread-2,5,main]}.
Task {0} iteration {4} thread {Thread[pool-1-thread-1,5,main]}.
Task {2} iteration {1} thread {Thread[pool-1-thread-1,5,main]}.
Task {1} iteration {4} thread {Thread[pool-1-thread-2,5,main]}.
Task {3} iteration {1} thread {Thread[pool-1-thread-2,5,main]}.
Task {2} iteration {2} thread {Thread[pool-1-thread-1,5,main]}.
Task {3} iteration {2} thread {Thread[pool-1-thread-2,5,main]}.
Task {2} iteration {3} thread {Thread[pool-1-thread-1,5,main]}.
Task {3} iteration {3} thread {Thread[pool-1-thread-2,5,main]}.
Task {2} iteration {4} thread {Thread[pool-1-thread-1,5,main]}.
...
showing that the first (thread pool size) tasks run to completion before the next tasks get scheduled.
What you need to do is create tasks which run for a while, then let other tasks run. Quite how you structure these depends on what you want to achieve
whether you want all the tasks to run at the same time, the all wait for a minute, then all run at the same time again, or whether the tasks are not synchronised with each other
whether you really wanted each task to run at a one-minute interval
whether your tasks are potentially blocking or not, and so really require separate threads
what behaviour is expected if a task blocks longer than the expected window for running
what behaviour is expected if a task blocks longer than the repeat rate (blocks for more than one minute)
Depending on the answers to these, some combination of ScheduledExecutorService, semaphores or mutexes can be used to co-ordinate the tasks. The simplest case is the non-blocking, non-synchronous tasks, in which case use a ScheduledExecutorService directly to run your runnables once every minute.
Can you rewrite your project for using some agent-based concurrency framework, like Akka?
You can certainly find some improvement in throughput by reducing the number of threads to what the system can realistically handle. Are you open to changing the design of the thread a bit? It'll unburden the scheduler to put the sleeping ones in a queue instead of actually having hundreds of sleeping threads.
class RepeatingWorker implements Runnable {
private ExecutorService executor;
private Date lastRan;
//constructor takes your executor
#Override
public void run() {
try {
if (now > lastRan + ONE_MINUTE) {
//do job
lastRan = now;
} else {
return;
} finally {
executor.submit(this);
}
}
}
This preserves your core semantic of 'job repeats indefinitely, but waits at least one minute between executions' but now you can tune the thread pool to something the machine can handle and the ones that aren't working are in a queue instead of loitering about in the scheduler as sleeping threads. There is some wait busy behavior if nobody's actually doing anything, but I am assuming from your post that the entire purpose of the application is to run these threads and it's currently railing your processors. You may need to tune around that if room has to be made for other things :)
You need a semaphore.
class AThread extends Thread {
Semaphore sem;
AThread(Semaphore sem) {
this.sem = sem;
}
public void run(){
while(true){
Thread.sleep(ONE_MINUTE);
sem.acquire();
try {
//Lots of computation every minute
} finally {
sem.release();
}
}
}
}
When instantiating the AThreads you need to pass the same semaphore instance:
Semaphore sem = new Semaphore(MAX_AVAILABLE, true);
Edit: Who voted down can please explain why? There is something wrong in my solution?

Categories

Resources