Search code examples
javamultithreadingthreadpoolthreadpoolexecutorjvisualvm

Why jvm recreate thread pool in case fixedThreadPool and don't do it in case of cachedThreadPool?


I have the code sample:

public class ThreadPoolTest {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            if (test() != 5 * 100) {
                throw new RuntimeException("main");
            }
        }
        test();

    }

    private static long test() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        CountDownLatch countDownLatch = new CountDownLatch(100 * 5);
        Set<Thread> threads = Collections.synchronizedSet(new HashSet<>());
        AtomicLong atomicLong = new AtomicLong();
        for (int i = 0; i < 5 * 100; i++) {
            Thread.sleep(100);
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        threads.add(Thread.currentThread());
                        atomicLong.incrementAndGet();
                        countDownLatch.countDown();
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        System.out.println(e);
                    }


                }
            });
        }
        executorService.shutdown();
        countDownLatch.await();
        if (threads.size() != 100) {
            throw new RuntimeException("test");
        }
        return atomicLong.get();
    }
}

I especially made application to work long.

And I see jvisualVM.
Each time gap threadpool was recreated.

After several minutes I see:

enter image description here

but if I use newCachedThreadPool instead of newFixedThreadPool I see constant picture:

enter image description here

Can you explain this behaviour?

P.S.

Problem was that exception occures in code and second iteration was not started


Solution

  • To answer your question; just look here:

    private static long test() throws InterruptedException {
      ExecutorService executorService = Executors.newFixedThreadPool(100);
    

    The JVM creates a new ThreadPool during each run of test(), because you tell it to do so.

    In other words: if you intend to re-use the same threadpool, then avoid creating/shutting down your instances all the time.

    In that sense, the simple fix is: move the creation of that ExecutorService into your main() method; and pass the service as argument to your test() method.

    Edit: regarding your last comment on cached vs. fixed threadpool; you probably want to look into this question.