Search code examples
javaconcurrencyexecutor

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);
    }
}

Solution

  • 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);
            }