Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executor does not handling tasks as expected

If I run long lasting tasks Executor never starts new threads if first task is not finished. Could someone please help me to understand why and how can I fix this?

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

public class TestExecutor {

    @Test
    public void test() throws InterruptedException {
        ExecutorService checkTasksExecutorService = new ThreadPoolExecutor(1, 10,
                100000, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());

        for (int i = 0; i < 20; i++) {
            checkTasksExecutorService.execute(new Runnable() {

                public  void run(){
                    try {
                        System.out.println(Thread.currentThread().getName() + "   running!");
                        Thread.sleep(10000);
                    } catch (Exception e) {
                    }

                }
            });
        }

        Thread.sleep(1000000);
    }
}
like image 686
user590444 Avatar asked Jul 27 '13 14:07

user590444


People also ask

How do you handle exceptions in Executor framework?

If you want to process exceptions thrown by the task, then it is generally better to use Callable rather than Runnable . If Callable. call() throws an exception, this will be wrapped in an ExecutionException and thrown by Future.

Should I shut down executor service?

ExecutorService must be shutdown explicitly to reclaim the resources (CPU & Memory) occupied by threads which have already finished their job but still exist.

How does an executor work internally?

The executor service creates and maintains a reusable pool of threads for executing submitted tasks. The service also manages a queue, which is used when there are more tasks than the number of threads in the pool and there is a need to queue up tasks until there is a free thread available to execute the task.


2 Answers

This is settled by the documentation:

When a new task is submitted in method execute(java.lang.Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.

So, to achieve the behavior you want, either increase the corePoolSize or give the executor service a non-growable queue, like this:

ExecutorService checkTasksExecutorService = new ThreadPoolExecutor(1, 20,
    100000, TimeUnit.MILLISECONDS,
    new SynchronousQueue<Runnable>());
like image 154
Marko Topolnik Avatar answered Nov 04 '22 21:11

Marko Topolnik


This behavior is due to the logic within the ThreadPoolExecutor where new threads are added if there is a failure to offer a task to the queue. Your queue is not bounded, so it effectively means that we will never grow above the core pool size and up to the maximum pool size.

Try this example to see the difference:

   ExecutorService checkTasksExecutorService = new ThreadPoolExecutor(1, 10,
                100000, TimeUnit.MILLISECONDS,
                new SynchronousQueue<Runnable>());

        for (int i = 0; i < 10; i++) {
            checkTasksExecutorService.execute(new Runnable() {

                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + "   running!");
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            });
        }

        //Thread.sleep(1000000); //instead this use following

//stop accepting new tasks
        checkTasksExecutorService.shutdown();

while (!checkTasksExecutorService.isTerminated()) {
            Thread.sleep(100);
        }
like image 40
Jk1 Avatar answered Nov 04 '22 22:11

Jk1