I have this simple schema:
int parallelism = 4; //4 tasks
ExecutorService executor = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(parallelism);
for(int i=0;i<parallelism;i++){
executor.execute(new MyTask());
}
latch.await();
System.out.println("done");
Where Task just calls
public void run(){
System.out.println("working");
latch.countDown();
}
Even though execution gives me:
working
working
working
working
done
the overall program keep executing! How come?
You need to shut down your Executor.
ExecutorService executor = Executors.newCachedThreadPool();
// ...
executor.shutdown();
while ( executor.awaitTermination(1, TimeUnit.SECONDS)) {
System.out.println("This is taking too long.");
}
Even though all of your runnables have completed the Executor keeps the threads in a pool. These are what is holding up your exit. The main thread will not exit until all non-daemon threads have completed.
Also see Turning an ExecutorService to daemon in Java for another alternative - making the Executor use daemon threads.
Related
I'm new to java concurrency an would like to ask the following basic question. I'm creating a ThreadPoolExecutor for imporving performance as follows:
int n = Runtime.getRuntime().availableProcessors()
ExecutorService executor = Executors.newFixedThreadPool(n);
for( int i = 0; i < n; i++)
executor.execute(new Work());
After all thread in the thread pool have finished their tasks I need to shutdown the pool properly. I would tried this:
while(true){
if(executor.isTerminated()){
executor.shutdownNow();
break;
}
}
But I'm not sure about that because I think we waste a lot of processors resources to queriyng the executor for termination.
What is the right solution for that?
UPD: Runnable task:
public class Work implements Runnable{
private String sql;
public Work() {
//init sql
}
#Override
public void run() {
JdbcTemplate template = new JdbcTemplate(dataSource);
#SuppressWarnings("unchecked")
List<Integer> ints = template.queryForList(sql, Integer.class);
//Storing the list into a global cache
}
}
There seems to be something mystical around shutting down an ExecutorService.
From the documentation of shutdown():
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
So all you have to do is to invoke shutdown() after you have submitted all your tasks, the exact time doesn’t matter. They don’t have to be completed at that time. The ThreadPoolExecutor will finish all tasks and then clean up all resources.
And it will do so regardless of whether you wait for it or not. So you don’t need to wait, just invoke shutdown() when you are confident that you will not submit new tasks, the rest will happen as soon as possible.
It says:
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()
So use awaitTermination instead. And for threads that take time, use a boolean variable as volatile and check it if it is set outside.If set then exit etc. something like that
try {
executor = Executors.newSingleThreadExecutor();
future = executor.submit(task);
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
}
finally {
if (Objects.nonNull(executor) && !executor.isTerminated()) {
LOGGER.error("cancelling all non-finished tasks");
}
if (Objects.nonNull(executor)) {
executor.shutdownNow();
LOGGER.info("shutdown finished");
}
}
This way you shutdown executor and waiting for 5 seconds to complete all tasks and then finally calling executor.shutdownNow() to completely kill the executor.
This is the best way to shutdown executor.
I am attempting to understand how to handle many instances of the ExecutorService executing Runnable commands. With regards to the code provided, how many shutdowns are required if I execute a hundred Runnables with the fixed thread pool set to one? I think the code should execute a hundred futures sequentially in the for loop execution order with a single thread (never spawns more than a single thread), and requires a single ExecutorService shutdown. Is this correct? Also, it's ok to call shutdown right after the for loop completes because all hundred of the futures are in queue so that the executorService shutdown will occur automatically after all hundred futures complete. Just looking for some clarification, thanks.
public static void main(String[] args)
{
private static ExecutorService executorService = Executors.newFixedThreadPool(1);
for (int i = 0; i < 100; i++)
{
executorService.execute(new Runnable() {
#Override
public void run()
{
// do stuff
}
});
}
executorService.shutdown();
}
Looks like you've got the right idea. It doesn't matter how many Runnables you've handed over to the ExecutorService to run or how big a thread pool you've allocated, you only need to call shutdown() once. That will allow all tasks to complete but will not allow you to add any new ones. You may want to call
try {
executorService.awaitTermination(5, TimeUnit.MINUTES);
} catch (InterruptedException e) {
// do stuff
}
to block while all tasks are completed depending on your usage scenario.
If you want to shutdown and attempt to kill all running tasks, instead call the shutdownNow() method. Note that there is no guarantee that it will be able to interrupt running tasks.
I want to set timeouts for threads which are executed within a thread pool. At the moment I have following code:
ExecutorService executor = Executors.newFixedThreadPool(8);
for(List<String> l: partition) {
Runnable worker = new WorkerThread(l);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
The code just splits a big list of objects into sublists and process these sublist within single threads. But this is not the point.
I want to give each single thread in the thread pool a timeout. For only one thread in the pool I found following solution:
Future<?> future = null;
for (List<String> l : partition) {
Runnable worker = new WorkerThread(l);
future = executor.submit(worker);
}
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
System.out.println("Terminated!");
}
But this would not work for more than one thread. Maybe I have to put each thread in a List<Future> list and iterate over this list and set a timeout for each future object?
Any suggestions?
EDIT AFTER USING CountDownLatch:
CountDownLatch doneSignal = new CountDownLatch(partition.size());
List<Future<?>> tasks = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(8);
for (List<String> l : partition) {
Runnable worker = new WorkerThread(l);
tasks.add(executor.submit(doneSignal, worker));
}
doneSignal.await(1, TimeUnit.SECONDS);
if (doneSignal.getCount() > 0) {
for (Future<?> fut : tasks) {
if (!fut.isDone()) {
System.out.println("Task " + fut + " has not finshed!");
//fut.cancel(true) Maybe we can interrupt a thread this way?!
}
}
}
Works good so far.
So next question is how to interrupt a thread which is timed out? I try fut.cancel(true) and add following construct in some critical loops in the worker thread:
if(Thread.interrupted()) {
System.out.println("!!Thread -> " + Thread.currentThread().getName() + " INTERRUPTED!!");
return;
}
So the worker thread is "killed" after the timeout. Is this a good solution?
Furthermore: Is it possible to get the name of the thread which timed out over the Future interface? At the moment I have to print out the name in the if condition of the Thread.interrupted() construct.
Thanks for help!
Regards
Have you seen this? ExecutorService.invokeAll
It should be exactly what you want: Invoke a bundle of workers and have them timeout if taking too long.
EDIT after comment - (new idea):
You can use a CountDownLatch to wait for the tasks to finish AND timeout via await(long timeout, TimeUnit unit)!
You can then even do a shutdownNow and see which tasks have taken too long ...
EDIT 2:
To make it clearer:
Have a CountDownLatch be count down by each Worker, when finished.
In the main execution thread await with timeout on said latch.
When that call returns, you can check the Latches's count to see if there has been the timeout hit (if it is >0).
a) count = 0, all tasks finished in time.
b) if not, loop the Futures and check their isDone. You don't have to call shutdown on the ExecutorService.
Call shutdown if you do not need the Executor any longer.
Note: Workers can finish in the meantime between the timeout and calling their Future's isDone().
Future future = executorService.submit(callable)
future.get(timeout, unit)
For more information see this link.
i'm new to this topic ... i'm using a ThreadPoolExecutor created with Executors.newFixedThreadPool( 10 ) and after the pool is full i'm starting to get a RejectedExecutionException .
Is there a way to "force" the executor to put the new task in a "wait" status instead of rejecting it and starting it when the pool is freed ?
Thanks
Issue regarding this
https://github.com/evilsocket/dsploit/issues/159
Line of code involved https://github.com/evilsocket/dsploit/blob/master/src/it/evilsocket/dsploit/net/NetworkDiscovery.java#L150
If you use Executors.newFixedThreadPool(10); it queues the tasks and they wait until a thread is ready.
This method is
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
As you can see, the queue used is unbounded (which can be a problem in itself) but it means the queue will never fill and you will never get a rejection.
BTW: If you have CPU bound tasks, an optimal number of threads can be
int processors = Runtime.getRuntime().availableProcessors();
ExecutorService es = Executors.newFixedThreadPool(processors);
A test class which might illustrate the situation
public static void main(String... args) {
ExecutorService es = Executors.newFixedThreadPool(2);
for (int i = 0; i < 1000 * 1000; i++)
es.submit(new SleepOneSecond());
System.out.println("Queue length " + ((ThreadPoolExecutor) es).getQueue().size());
es.shutdown();
System.out.println("After shutdown");
try {
es.submit(new SleepOneSecond());
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
static class SleepOneSecond implements Callable<Void> {
#Override
public Void call() throws Exception {
Thread.sleep(1000);
return null;
}
}
prints
Queue length 999998
After shutdown
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask#e026161 rejected from java.util.concurrent.ThreadPoolExecutor#3e472e76[Shutting down, pool size = 2, active threads = 2, queued tasks = 999998, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2013)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:816)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1337)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:132)
at Main.main(Main.java:17)
It is very possible that a thread calls exit, which sets mStopped to false and shutdowns the executor, but:
your running thread might be in the middle of the while (!mStopped) loop and tries to submit a task to the executor which has been shutdown by exit
the condition in the while returns true because the change made to mStopped is not visible (you don't use any form of synchronization around that flag).
I would suggest:
make mStopped volatile
handle the case where the executor is shutdown while you are in the middle of the loop (for example by catching RejectedExecutionException, or probably better: shutdown your executor after your while loop instead of shutting it down in your exit method).
Building on earlier suggestions, you can use a blocking queue to construct a fixed size ThreadPoolExecutor. If you then supply your own RejectedExecutionHandler which adds tasks to the blocking queue, it will behave as described.
Here's an example of how you could construct such an executor:
int corePoolSize = 10;
int maximumPoolSize = 10;
int keepAliveTime = 0;
int maxWaitingTasks = 10;
ThreadPoolExecutor blockingThreadPoolExecutor = new ThreadPoolExecutor(
corePoolSize, maximumPoolSize,
keepAliveTime, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(maxWaitingTasks),
new RejectedExecutionHandler() {
#Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while submitting task", e);
}
}
});
If I understand correctly, you have your ThreadPool created with fixed number of threads but you might have more tasked to be submitted to the thread pool. I would calcuate the keepAliveTime based on the request and set it dynamically. That way you would not have RejectedExecutionException.
For example
long keepAliveTime = ((applications.size() * 60) / FIXED_NUM_OF_THREADS) * 1000;
threadPoolExecutor.setKeepAliveTime(keepAliveTime, TimeUnit.MILLISECONDS);
where application is a collection of task that could be different every time.
That should solve your problem if you know average time the task take.
I've got a multi-threaded application. When using Thread.start() to manually start threads every concurrent thread uses exactly 25% CPU (or exactly one core - this is on a quad core machine). So if I run two threads CPU usage is exactly 50%.
When using ExecutorService to run threads however, there seems to be one "ghost" thread consuming CPU resources! One Thread uses 50% instead of 25%, two thread use 75%, etc.
Could this be some kind of windows task manager artefact?
Excutor service code is
ExecutorService executor = Executors.newFixedThreadPool(threadAmount);
for (int i = 1; i < 50; i++) {
Runnable worker = new ActualThread(i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
and Thread.start() code is:
ActualThread one= new ActualThread(2,3);
ActualThread two= new ActualThread(3,4);
...
Thread threadOne = new Thread(one);
Thread threadTtwo = new Thread(two);
...
threadOne.start();
threadTwo.start();
...
Here's your problem:
while (!executor.isTerminated()) {
}
Your "main" method is spinning the CPU doing nothing. Use invokeAll() instead, and your thread will block without a busy wait.
final ExecutorService executor = Executors.newFixedThreadPool(threadAmount);
final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
for (int i = 1; i < 50; i++) {
tasks.add(Executors.callable(new ActualThread(i)));
}
executor.invokeAll(tasks);
executor.shutdown(); // not really necessary if the executor goes out of scope.
System.out.println("Finished all threads");
Since invokeAll() wants a collection of Callable, note the use of the helper method Executors.callable(). You can actually use this to get a collection of Futures for the tasks as well, which is useful if the tasks are actually producing something you want as output.