gstackoverflow
gstackoverflow

Reputation: 37034

Why threadpool creates only one thread?

I have wrote code sample:

class Test {
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(0, 100,
                2L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>());
        executorService.allowCoreThreadTimeOut(true);

        CountDownLatch countDownLatch = new CountDownLatch(20);
        long l = System.currentTimeMillis();
        for (int i = 0; i < 20; i++) {
            Thread.sleep(100);
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.countDown();
                        Thread.sleep(500);
                    } catch (Exception e) {
                        System.out.println(e);
                    }


                }
            });
        }
        executorService.shutdown();
        countDownLatch.await();

        System.out.println((System.currentTimeMillis() - l) / 100);
    }
}

Each 100 ms submits new task(overall task quantity - 20). Each task duration - 0.5 sec. thus 5 task can be executed in parallel and best execution time will be: 20*100+500 = 2.5 sec and pool should create 5 threads

enter image description here

But my experiment shows 9.6 sec.
I opened the jsvisualvm to see how many threads pool creates and I see that only one thread was created:

enter image description here

please correct where my threadPooll configuration incorrect.

Upvotes: 4

Views: 3442

Answers (2)

GhostCat
GhostCat

Reputation: 140427

I guess the answer to this behavior could be rooted in:

A ThreadPoolExecutor will automatically adjust the pool size (see getPoolSize()) according to the bounds set by corePoolSize (see getCorePoolSize()) and maximumPoolSize (see getMaximumPoolSize()). 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.

( from ThreadPoolExecutor javadoc ).

Thing is: how are sleeping threads coming into this equation. My suggestion: change the corePoolSize from 0 to 10; and set the max pool size to 10, too.

Upvotes: 0

Kayaman
Kayaman

Reputation: 73558

The reason can be found from the ThreadPoolExecutor javadoc.

Any BlockingQueue may be used to transfer and hold submitted tasks.

The use of this queue interacts with pool sizing: If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.

If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.

If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

Therefore since your corePoolSize is 0, the first option is not used and since your queue is unlimited, the last option is not used. Therefore the remaining strategy of queuing is what you get.

Different results can be seen by modifying corePoolSize or the size of the workQueue.

Upvotes: 4

Related Questions