As in my previous Spring articles, we’ll review some of the points by doing some demos and experiments. This article starts with the thread pool that is most commonly used in Java concurrency.

Start with a thread pool experiment

First we write a method that outputs basic thread pool information once per second:

private void printStats(ThreadPoolExecutor threadPool){
    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
        log.info("= = = = = = = = = = = = = = = = = = = = = = = = =");
        log.info("Pool Size: {}", threadPool.getPoolSize());
        log.info("Active Threads: {}", threadPool.getActiveCount());
        log.info("Number of Tasks Completed: {}", threadPool.getCompletedTaskCount());
        log.info("Number of Tasks in Queue: {}", threadPool.getQueue().size());

        log.info("= = = = = = = = = = = = = = = = = = = = = = = = =");
    }, 0.1, TimeUnit.SECONDS);
}
Copy the code

Then, we write a method to periodically submit tasks to the thread pool:

private void submitTasks(AtomicInteger atomicInteger, ThreadPoolExecutor threadPool) {
    IntStream.rangeClosed(1.20).forEach(i -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int id = atomicInteger.incrementAndGet();
        threadPool.submit(() -> {
            log.info("{} started", id);
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("{} finished", id);
        });
    });
}
Copy the code

You can see:

  • A total of 20 tasks were submitted
  • Submit one task per second
  • Each task takes 10 seconds
  • Task content is very simple, is the counter stack

Now we write a common thread pool and wait for all tasks in the pool to complete:

@Test
public void test1(a) throws InterruptedException {
    AtomicInteger atomicInteger = new AtomicInteger();
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
            2.5.5, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(10));

    printStats(threadPool);
    submitTasks(atomicInteger,threadPool);
    threadPool.shutdown();
    threadPool.awaitTermination(1, TimeUnit.HOURS);
}
Copy the code

As you can see, the thread pool is:

  • Two core threads
  • Five maximum threads
  • 5 second recycle limit (maximum) thread
  • The queue has a maximum of 10 tasks

For this configuration, think about how the thread pool works after the task has been submitted. Throw up a few questions:

  • How many threads will there be in the pool to start with?
  • How many threads will the pool become?
  • Can these tasks be performed?

Let’s observe the output after executing:

09:51:37. 709 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:37. 715 INFO [2 - thread pool - - 1] me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0 09:51:37. [2 - thread pool - 718-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 0 09:51:37. [2 - thread pool - 718-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:37. [2 - thread pool - 718-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 0 09:51:37. [2 - thread pool - 718-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:38. 705 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:38. 705 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0 09:51:38. [2 - thread pool - 705-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 0 09:51:38. [2 - thread pool - 705-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:38. [2 - thread pool - 705-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 0 09:51:38. [2 - thread pool - 705-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:38. [] - thread pool - 1-1 of 716 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 1 started 09:51:39.. 701] [the pool - 2 - thread - 1 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 09:51:39. 701 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 1 09:51:39. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 1 09:51:39. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:39. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 0 09:51:39. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:39. 718 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 2 started 09:51:40.. 704] [the pool - 2 - thread - 1 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 09:51:40. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 2 09:51:40. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:40. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:40. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 0 09:51:40. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:41. 701 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:41. 701 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:41. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:41. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:41. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 1 09:51:41. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:42. 702 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:42. 702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:42. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:42. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:42. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 2 09:51:42. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:43. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:43. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:43. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:43. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:43. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 3 09:51:43. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:44. 701 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:44. 701 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:44. [2 - thread pool - 701-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:44. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:44. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 4 09:51:44. [2 - thread pool - 702-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:45. 702 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:45. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:45. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:45. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:45. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 5 09:51:45. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:46. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:46. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:46. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:46. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:46. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 6 09:51:46. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:47. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:47. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:47. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:47. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:47. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 7 09:51:47. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:48. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:48. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:48. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:48. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 09:51:48. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 8 09:51:48. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:48. [] - thread pool - 1-1 of 719 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 1 finished 09:51:48. [] - thread pool - 1-1 of 719 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 3 started 09:51:49. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:49. 703 INFO [2 - thread pool - - 1] me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:49. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:49. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 1 09:51:49. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 8 09:51:49. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:49. 720 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 2 finished 09:51:49. 720 / - thread pool - 1-2 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 4 started 09:51:50. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:50. 703 INFO [2 - thread pool - - 1] me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:50. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:50. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:50. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 8 09:51:50. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:51. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:51. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:51. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:51. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:51. [2 - thread pool - 704-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 9 09:51:51. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:52. 703 INFO [2 - thread pool - - 1] Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:52. 703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2 09:51:52. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 09:51:52. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:52. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 10 09:51:52. 703 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:52. 749 / - thread pool - 1-3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 15 started 09:51:53.. 703] [the pool - 2 - thread - 1 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 09:51:53. 703 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 3 09:51:53. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 3 09:51:53. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:53. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 10 09:51:53. 703 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:53, 754 [- thread pool - 1-4] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 16 started 09:51:54.. 703] [the pool - 2 - thread - 1 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 09:51:54. 703 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 4 09:51:54. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 4 09:51:54. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:54. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 10 09:51:54. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 09:51:54. 755 / - thread pool - 1-5 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 17 started 09:51:55.. 703] [the pool - 2 - thread - 1 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 09:51:55. 703 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 5 09:51:55. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 09:51:55. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 09:51:55. [2 - thread pool - 703-1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasksinqueue: 10 09:51:55. 704 [pool - 2 - thread - 1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - ========================= java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@fdefd3f[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1a0dcaa[Wrapped task = me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest$$Lambda$50/0x0000000800105840@3bd40a57]] rejected from java.util.concurrent.ThreadPoolExecutor@d83da2e[Running, pool size = 5, active threads = 5, queued tasks = 10, completed tasks = 2]

	at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2055)
	at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:825)
	at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1355)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
	at me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest.lambda$submitTasks$2(ThreadPoolExecutorTest.java:33)
	at java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:104)
	at java.base/java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:593)
	at me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest.submitTasks(ThreadPoolExecutorTest.java:26)
	at me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest.test1(ThreadPoolExecutorTest.java:54)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethodThe $1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunnerThe $1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.accessThe $000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Copy the code

You can see from the output:

  • Though equipped with two core thread, thread pool threads or zero at the beginning, you can use the threadPool. PrestartAllCoreThreads () to change the behavior, initialize all the core of the thread
  • As the task is submitted, the core thread slowly initializes, up to two core threads
  • Since tasks take 10 seconds to execute, the queue gradually accumulates tasks to 10
  • The pool then continues to add threads until the maximum number of threads is 5
  • When the maximum number of threads is 5, and the queue is 10 full, there are still tasks coming in and there will be a denial exception

As we know, Java thread pools by default prefer to use queues to hold tasks rather than more threads to digest them, and only use more thread pools to temporarily handle a sudden increase in tasks when the queue is full. Sometimes, we actually prefer the more radical approach, where thread pools open more threads first, and queues are used as a backup. If the thread pool is flexible to a maximum of 5 threads, then after 20 seconds there will be 5 tasks executing, 5 tasks already completed, and 10 more in the thread pool. All of these tasks can be completed eventually. Rather than slow tasks being processed because the thread pool was expanding too late.

We can do this by Hack:

@Test
public void test2(a) throws InterruptedException {
    AtomicInteger atomicInteger = new AtomicInteger();

    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(10) {
        @Override
        public boolean offer(Runnable e) {
            return false; }}; ThreadPoolExecutor threadPool =new ThreadPoolExecutor(
            2.5.5, TimeUnit.SECONDS,
            queue, new ThreadFactoryImpl("elastic-pool"), (r, executor) -> {
        try {
            executor.getQueue().put(r);
        } catch(InterruptedException e) { Thread.currentThread().interrupt(); }}); threadPool.allowCoreThreadTimeOut(true);
    printStats(threadPool);
    submitTasks(atomicInteger,threadPool);
    threadPool.shutdown();
    threadPool.awaitTermination(1, TimeUnit.HOURS);
}
Copy the code

This feature relies on two major improvements:

  • We need to override the queue’s offer method to return false, so that the thread pool will have the illusion that the queue is full. The offer method is defined as follows:
  • RejectedExecutionHandler specifies a custom reject handler to initialize the thread pool, and then to insert the task into the queue. RejectedExecutionHandler defines the following:

Let’s look at the output:

10:53:37. [889] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:37. [] - thread pool - 1-1 of 898 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0 10:53:37. [901] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 0 10:53:37. [901] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:37. [901] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:37. [901] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:38. [] - thread pool - 1-1 of 879 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:38. 879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0 10:53:38. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 0 10:53:38. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:38. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:38. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:38. 919 / elastic - pool1 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 1 started 10:53:39. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:53:39. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 1 10:53:39. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 1 10:53:39. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:39. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:39. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:39. 924 / elastic - pool2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 2 started 10:53:40. [] - thread pool - 1-1 of 877 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:53:40. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 2 10:53:40. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 10:53:40. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:40. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:40. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:40. 930 / elastic - pool3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 3 started 10:53:41. [] - thread pool - 1-1 of 879 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:53:41. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 3 10:53:41. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 3 10:53:41. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:41. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:41. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:41. 934 / elastic - pool4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 4 started 10:53:42. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:53:42. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 4 10:53:42. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 4 10:53:42. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:42. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:42. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:42. 935 / elastic - pool5 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 5 started 10:53:43. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:53:43. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 5 10:53:43. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:43. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:43. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:53:43. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:44. [] - thread pool - 1-1 of 881 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:44. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:44. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:44. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:44. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 1 10:53:44. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:45. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:45. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:45. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:45. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:45. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 2 10:53:45. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:46. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:46. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:46. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:46. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:46. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 3 10:53:46. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:47. [] - thread pool - 1-1 of 880 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:47. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:47. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:47. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:47. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 4 10:53:47. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:48. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:48. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:48. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:48. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 0 10:53:48. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:48. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:48. 921 / elastic - pool1 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 1 finished 10:53:48, 922 [elastic - pool1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 6 started 10:53:49. 882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:49. [] - thread pool - 1-1 of 882 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:49. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:49. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 1 10:53:49. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:49. [883] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:49. 927 / elastic - pool2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 2 finished 10:53:49, 928 [elastic - pool2] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 7 started 10:53:50. 879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:50. [] - thread pool - 1-1 of 879 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:50. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:50. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 2 10:53:50. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:50. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:50. 933 / elastic - pool3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 3 finished 10:53:50, 933 [elastic - pool3] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 8 started 10:53:51. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:51. [] - thread pool - 1-1 of 881 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:51. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:51. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 3 10:53:51. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:51. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:51. 935 / elastic - pool4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 4 finished 10:53:51, 935 [elastic - pool4] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 9 started 10:53:52. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:52. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:52. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:52. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 4 10:53:52. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:52. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:52. 937 / elastic - pool5 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 5 finished 10:53:52, 938 [elastic - pool5] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 10 started 10:53:53. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:53. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:53. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:53. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:53. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:53:53. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:54. [] - thread pool - 1-1 of 880 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:54. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:54. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:54. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:54. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 6 10:53:54. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:55. [] - thread pool - 1-1 of 880 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:55. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:55. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:55. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:55. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 7 10:53:55. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:56. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:56. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:56. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:56. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:56. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 8 10:53:56. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:57. [] - thread pool - 1-1 of 881 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:57. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:57. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:57. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:57. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 9 10:53:57. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:58. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:58. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:58. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:58. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 5 10:53:58. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 10 10:53:58. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:58. 923 / elastic - pool1 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 6 finished 10:53:58, 923 [elastic - pool1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 11 started 10:53:59. 879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:59. [] - thread pool - 1-1 of 879 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:53:59. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:53:59. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 6 10:53:59. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 9 10:53:59. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:53:59. 931 / elastic - pool2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 7 finished 10:53:59, 931 [elastic - pool2] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 12 started 10:54:00. 883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:00. [] - thread pool - 1-1 of 883 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:00. [883] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:00. [883] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 7 10:54:00. [883] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 8 10:54:00. [883] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:00. 937 / elastic - pool3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 8 finished 10:54:00, 938 [elastic - pool3] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 13 started 10:54:01. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:01. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:01. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:01. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 8 10:54:01. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 7 10:54:01. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:01. 937 / elastic - pool4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 9 finished 10:54:01, 937 [elastic - pool4] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 14 started 10:54:02. 879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:02. [] - thread pool - 1-1 of 879 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:02. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:02. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 9 10:54:02. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 6 10:54:02. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:02. 941 / elastic - pool5 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 10 finished 10:54:02, 941 [elastic - pool5] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 15 started 10:54:03. 880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:03. [] - thread pool - 1-1 of 880 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:03. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:03. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:03. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:03. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:04. [] - thread pool - 1-1 of 878 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:04. 879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:04. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:04. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:04. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:04. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:05. [] - thread pool - 1-1 of 878 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:05. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:05. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:05. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:05. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:05. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:06. [] - thread pool - 1-1 of 881 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:06. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:06. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:06. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:06. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:06. [881] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:07. [] - thread pool - 1-1 of 881 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:07. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:07. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:07. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:07. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:07. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:08. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:08. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:08. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:08. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 10 10:54:08. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 5 10:54:08. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:08. 927 / elastic - pool1 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 11 finished 10:54:08, 928 [elastic - pool1] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 16 started 10:54:09. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:09. [] - thread pool - 1-1 of 879 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:09. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:09. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 11 10:54:09. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 4 10:54:09. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:09. 933 / elastic - pool2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 12 finished 10:54:09, 933 [elastic - pool2] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 17 started 10:54:10. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:10. [] - thread pool - 1-1 of 878 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:10. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:10. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 12 10:54:10. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 3 10:54:10. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:10. 942 / elastic - pool3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 13 finished 10:54:10, 942 [elastic - pool3] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 18 started 10:54:11. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:11. [] - thread pool - 1-1 of 877 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:11. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:11. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 13 10:54:11. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 2 10:54:11. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:11. 939 / elastic - pool4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 14 finished 10:54:11, 939 [elastic - pool4] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 19 started 10:54:12. 881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:12. [] - thread pool - 1-1 of 882 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:12. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:12. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 14 10:54:12. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 1 10:54:12. [882] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:12. 946 / elastic - pool5 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 15 finished 10:54:12, 946 [elastic - pool5] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 20 started 10:54:13. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:13. [] - thread pool - 1-1 of 878 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:13. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:13. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:13. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:13. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:14. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:14. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:14. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:14. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:14. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:14. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:15. [] - thread pool - 1-1 of 878 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:15. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:15. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:15. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:15. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:15. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:16. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:16. 877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:16. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:16. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:16. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:16. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:17. [] - thread pool - 1-1 of 878 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:17. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:17. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:17. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:17. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:17. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:18. [] - thread pool - 1-1 of 877 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:18. 878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5 10:54:18. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 5 10:54:18. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 15 10:54:18. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:18. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:18. 929 / elastic - pool1 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 16 finished 10:54:19. [] - thread pool - 1-1 of 880  INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:54:19. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 4 10:54:19. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 4 10:54:19. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 16 10:54:19. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:19. [880] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:19. 938 / elastic - pool2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 17 finished 10:54:20. [] - thread pool - 1-1 of 879  INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:54:20. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 3 10:54:20. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 3 10:54:20. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 17 10:54:20. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:20. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:20. 947 / elastic - pool3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 18 finished 10:54:21. [] - thread pool - 1-1 of 878  INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:54:21. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 2 10:54:21. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 2 10:54:21. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 18 10:54:21. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:21. [879] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:21. 943 / elastic - pool4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. ThreadPoolExecutorTest - 19 finished 10:54:22. [] - thread pool - 1-1 of 877  INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - ========================= 10:54:22. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - pool Size: 1 10:54:22. [877] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Active Threads: 1 10:54:22. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of Tasks Completed: 19 10:54:22. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - Number of TasksinQueue: 0 10:54:22. [878] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. ThreadPoolExecutorTest - = = = = = = = = = = = = = = = = = = = = = = = = = 10:54:22. 950 / elastic - pool5 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 20 finishedCopy the code

As can be seen from this result:

  • The thread pool is not pre-initialized, so it still has zero threads
  • And then you go straight to the maximum thread of 5 threads
  • All tasks can be performed
  • Finally, because we have allowCoreThreadTimeOut enabled, the core thread can also be reclaimed

Actually, here also can think of another way of thinking, we hope that in the case of high concurrency, thread pool can more actively create a thread, so we can initialize the thread pool initialization five core thread, when I was five biggest thread, and then open the core thread, so also can save the thread in concurrent low.

When a queue returns false, it is a matter of knowledge. If you do not have a buffer, it is not necessary to create a new thread, which will return false. Later we will talk about the tomcat thread pool implementation.

Name the thread in the thread pool

In the previous tests we used a custom thread factory class to name threads:

public class ThreadFactoryImpl implements ThreadFactory {
    private final AtomicLong threadIndex = new AtomicLong(0);
    private final String threadNamePrefix;
    private final boolean daemon;

    public ThreadFactoryImpl(final String threadNamePrefix) {
        this(threadNamePrefix, false);
    }

    public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon) {
        this.threadNamePrefix = threadNamePrefix;
        this.daemon = daemon;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet());
        thread.setDaemon(daemon);
        returnthread; }}Copy the code

This is a good practice, for complex projects that must have N thread pools, having a clear and easily identifiable name makes it easier to troubleshoot problems when they occur.

Tomcat thread pool

The Tomcat thread pool has made some improvements over the native thread pool in three main areas:

  • Initialize the core threads at the beginning, and they’re bound to fill up later, so why not initialize them at the beginning
  • As before, it is possible to use enough threads instead of using queues first (Tomcat queues are infinitely long, so this ensures that the largest thread can be used, otherwise this configuration is meaningless)
  • A final attempt is made to submit the task to the queue when the queue is full and a waiting time is allowed

Let’s start with the queue. We’ll focus on the overridden offer method, which returns false to increase the timing of the thread:

@Slf4j
public class TomcatTaskQueue extends LinkedBlockingQueue<Runnable> {

private transient volatile TomcatThreadPool parent = null;

public TomcatTaskQueue(int capacity) {
    super(capacity);
}

public void setParent(TomcatThreadPool tp) {
    parent = tp;
}

public boolean force(Runnable o) {
    if (parent == null || parent.isShutdown())
        throw new RejectedExecutionException("taskQueue.notRunning");
    return super.offer(o); //forces the item onto the queue, to be used if the task is rejected
}

public boolean force(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
    if (parent == null || parent.isShutdown())
        throw new RejectedExecutionException("taskQueue.notRunning");
    return super.offer(o, timeout, unit); //forces the item onto the queue, to be used if the task is rejected
}

@Override
public boolean offer(Runnable o) {
    //we can't do any checks
    if (parent == null)
        return super.offer(o);
    //we are maxed out on threads, simply queue the object
    if (parent.getPoolSize() == parent.getMaximumPoolSize()) {
        log.info("pool==max, getPoolSize: {}, getMaximumPoolSize:{}, task:{}", parent.getPoolSize(), parent.getMaximumPoolSize(), o);
        return super.offer(o);
    }
    //we have idle threads, just add it to the queue
    if (parent.getSubmittedCount() <= (parent.getPoolSize())) {
        log.info("submit<=pool, getPoolSize: {}, getMaximumPoolSize:{}, task:{}", parent.getPoolSize(), parent.getMaximumPoolSize(), o);
        return super.offer(o);
    }
    //if we have less threads than maximum force creation of a new thread
    if (parent.getPoolSize() < parent.getMaximumPoolSize()) {
        log.info("Grow thread pool, getPoolSize: {}, getMaximumPoolSize:{}", parent.getPoolSize(), parent.getMaximumPoolSize());
        return false;
    }
    //if we reached here, we need to add it to the queue
    log.info("else, getPoolSize: {}, getMaximumPoolSize:{}, task:{}", parent.getPoolSize(), parent.getMaximumPoolSize(), o);
    return super.offer(o);
}
Copy the code

Next comes the thread pool area, where we focus on the handling strategy if an exception is rejected:

@Slf4j
public class TomcatThreadPool extends java.util.concurrent.ThreadPoolExecutor {

    /**
     * The number of tasks submitted but not yet finished. This includes tasks
     * in the queue and tasks that have been handed to a worker thread but the
     * latter did not start executing the task yet.
     * This number is always greater or equal to {@link #getActiveCount()}.
     */
    private final AtomicInteger submittedCount = new AtomicInteger(0);

    public TomcatThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        prestartAllCoreThreads();
    }

    public TomcatThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
                            RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        prestartAllCoreThreads();
    }

    public TomcatThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, new RejectHandler());
        prestartAllCoreThreads();
    }

    public TomcatThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new RejectHandler());
        prestartAllCoreThreads();
    }

    public int getSubmittedCount(a) {
        return submittedCount.get();
    }

    / * * * {@inheritDoc} * /
    @Override
    public void execute(Runnable command) {
        execute(command, 0, TimeUnit.MILLISECONDS);
    }

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     * If no threads are available, it will be added to the work queue.
     * If the work queue is full, the system will wait for the specified
     * time and it throw a RejectedExecutionException if the queue is still
     * full after that.
     *
     * @param command the runnable task
     * @param timeout A timeout for the completion of the task
     * @param unit    The timeout time unit
     * @throws RejectedExecutionException if this task cannot be
     *                                    accepted for execution - the queue is full
     * @throws NullPointerException       if command or unit is null
     */
    public void execute(Runnable command, long timeout, TimeUnit unit) {
        submittedCount.incrementAndGet();
        try {
            super.execute(command);
        } catch (RejectedExecutionException rx) {
            if (super.getQueue() instanceof TomcatTaskQueue) {
                final TomcatTaskQueue queue = (TomcatTaskQueue) super.getQueue();
                try {
                    if(! queue.force(command, timeout, unit)) { submittedCount.decrementAndGet();throw new RejectedExecutionException("threadPoolExecutor.queueFull");
                    } else {
                        log.warn("RejectedExecutionException throw, task {} put into queue again", command.toString()); }}catch (InterruptedException x) {
                    submittedCount.decrementAndGet();
                    throw newRejectedExecutionException(x); }}else {
                submittedCount.decrementAndGet();
                throwrx; }}}private static class RejectHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor executor) {
            throw newRejectedExecutionException(); }}}Copy the code

Now write some test code:

@Slf4j
public class TomcatThreadPoolTest {

    @Test
    public void test(a) throws InterruptedException {
        TomcatTaskQueue taskqueue = new TomcatTaskQueue(5);
        TomcatThreadPool threadPool = new TomcatThreadPool(2.5.60, TimeUnit.SECONDS, taskqueue);
        taskqueue.setParent(threadPool);
        IntStream.rangeClosed(1.10).forEach(i -> threadPool.execute(new Task(true, i)));
        IntStream.rangeClosed(1.10).forEach(i -> threadPool.execute(new Task(false, i)
                , 1050, TimeUnit.MILLISECONDS));

        threadPool.shutdown();
        threadPool.awaitTermination(1, TimeUnit.HOURS);
    }

    @ToString
    class Task implements Runnable {
        private boolean slow;
        private String name;

        public Task(boolean slow, int index) {
            this.slow = slow;
            this.name = String.format("%s-%d", slow ? "slow" : "quick", index);
        }

        @Override
        public void run(a) {
            log.info("Start:{}", name);
            if (slow) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            log.info("Finish:{}", name); }}}Copy the code

In the test code, our queue is only 5, our maximum thread is also 5, and our slow task is 10, because our task is allowed to wait 1050ms to try to submit to the queue, so based on this configuration, our fast task can be successfully executed without error:

16:38:36. 117 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatTaskQueue - submit < = pool, getPoolSize: 2, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = missile - 1) 16:38:36. [165 - thread pool - 1-1] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: 16:38:36 missile - 1, 166 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - submit<=pool, getPoolSize: 2, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = missile - 2) 16:38:36. 166 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 2 16:38:36. [the main] 166 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 2, GetMaximumPoolSize: 5 16:38:36. 166 / - thread pool - 1-3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 3 16:38:36. [the main] 166 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 3, GetMaximumPoolSize: 5 16:38:36. [167] - thread pool - 1-4 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 4 16:38:36. [the main] 167 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 4, GetMaximumPoolSize: 5 16:38:36. [167 - thread pool - 1-5) INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 5 16:38:36. [the main] 168 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = missile - 6) 16:38:36. 168 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = missile - 7) 16:38:36. 168 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = 16:38:36 missile - 8). The 169 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = 16:38:36 missile - 9), 169 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true. Name = missile - 10) 16:38:36. 170 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max,  getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 1) 16:38:37. 169 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 2 16:38:37. 169 / - thread pool - 1-1 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: 16:38:37 missile - 1. 169 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-7 16:38:37. 169 / - thread pool - 1-2 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Start: missile - 6 16:38:37. 169 [main] WARN me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPool - RejectedExecutionException throw, task TomcatThreadPoolTest.Task(slow=false. Name =quick-1) put into queue again 16:38:37.169 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 2) 16:38:37. 170 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max,  getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 3) 16:38:37. [170 - thread pool - 1-4] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 4 16:38:37. 170 / - thread pool - 1-3 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 3 16:38:37. 170 [pool-1-thread-5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-5 16:38:37. [170] - thread pool - 1-4 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Start: 8 16:38:37 missile - 170 [main] WARN me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPool - RejectedExecutionException throw, task TomcatThreadPoolTest.Task(slow=false. Name =quick-3) put into queue again 16:38:37.170 [pool-1-thread-5] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 10 16:38:37. 170 / - thread pool - 1-3 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: missile - 9 16:38:37. [the main] 171 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 4) 16:38:37. 171 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max,  getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 5) 16:38:37. 171 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max,  getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 6) 16:38:38. [171 - thread pool - 1-1] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 7 16:38:38. 171 / - thread pool - 1-2 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 6 16:38:38. 172 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-1 16:38:38. 172 [main] WARN me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPool - RejectedExecutionException throw, task TomcatThreadPoolTest.Task(slow=false. Name =quick-6) put into queue again 16:38:38.172 [pool-1-thread-2] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 2 16:38:38. 172 / - thread pool - 1-1 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: 16:38:38 quick - 1. 172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-2 16:38:38. [172] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Start: quick - 3 16:38:38. 172 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 4 16:38:38. 172 / - thread pool - 1-1 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: quick - 3 16:38:38. 172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-4 16:38:38. [172] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Start: quick - 5 16:38:38. 172 [main] INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatTaskQueue - pool = = Max,  getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 7) 16:38:38. 172 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 6 16:38:38. 172 / - thread pool - 1-1 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: quick - 5 16:38:38. 172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-6 16:38:38. [172] - thread pool - 1-1 the INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Start: quick - 7 16:38:38. [172] - thread pool - 1-1 of the INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: quick - 7 16:38:38. [the main] 172 INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 8) 16:38:38. 173 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 8 16:38:38. 173 / - thread pool - 1-2 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: quick - 8 16:38:38. 173 (main) INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 9) 16:38:38. [173 - thread pool - 1-1] INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 9 16:38:38. 173 / - thread pool - 1-1 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: quick - 9 16:38:38. 173 (main) INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false. Name = quick - 10) 16:38:38. 173 / - thread pool - 1-2 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Start: quick - 10 16:38:38. 174 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-10 16:38:38. [175] - thread pool - 1-4 INFO me. Josephzhu. Javaconcurrenttest. Concurrent. The executors. TomcatThreadPoolTest - Finish: missile - 8 16:38:38. 175 / - thread pool - 1-3 INFO Me. Josephzhu. Javaconcurrenttest. Concurrent. Executors. TomcatThreadPoolTest - Finish: missile - 9 16:38:38. 175 / - thread pool - 1-5  INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-10Copy the code

RejectedExecutionException attention to log in several times, but after waiting for tasks are submitted to the queue.

Predefined thread pools

Take a look at the two so-called common thread pools predefined by Executors:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newCachedThreadPool(a) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
    
Copy the code

A fixed-size thread pool is one in which threads are fixed in size but the queue is unbounded. Obviously, if the tasks are too many and too slow for the thread pool to handle, then the unbounded queue may cause OOM. This is a risk:

There’s also something called a cache thread pool, which means threads are cached, recycled in 60 seconds, created as needed, unlimited number of threads, created as needed. This is also extreme and may create multiple threads, which will also result in OOM:

I’m not going to give you the test code, but you can do it yourself. So ali Java development manual does not recommend using these two predefined thread pools, we should control the thread pool according to the need:

  • Queue type
  • The queue length
  • Core threads
  • Maximum number of threads
  • Recovery time
  • Whether to reclaim the core thread
  • Whether the core thread is pre-created
  • Rejection processing mode
  • Thread factory

Paused thread pool

Here we give an official example of implementing a pauseable thread pool by implementing a custom beforeExecute.

The thread pool code is as follows:

public class PausableThreadPoolExecutor extends ThreadPoolExecutor {
    private boolean isPaused;
    private ReentrantLock pauseLock = new ReentrantLock();
    private Condition unpaused = pauseLock.newCondition();

    public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }
    
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        pauseLock.lock();
        try {
            while (isPaused) unpaused.await();
        } catch (InterruptedException ie) {
            t.interrupt();
        } finally{ pauseLock.unlock(); }}public void pause(a) {
        pauseLock.lock();
        try {
            isPaused = true;
        } finally{ pauseLock.unlock(); }}public void resume(a) {
        pauseLock.lock();
        try {
            isPaused = false;
            unpaused.signalAll();
        } finally{ pauseLock.unlock(); }}}Copy the code

Try writing some test code:

@Test
public void test(a) throws InterruptedException {
    PausableThreadPoolExecutor threadPool = new PausableThreadPoolExecutor(1.1.0,TimeUnit.HOURS,new LinkedBlockingQueue<>());
    IntStream.rangeClosed(1.5).forEach(i->threadPool.submit(()->{
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("I'm done : {}", i);
    }));
    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    scheduler.schedule(threadPool::pause, 2, TimeUnit.SECONDS);
    scheduler.schedule(threadPool::resume, 4, TimeUnit.SECONDS);

    threadPool.shutdown();
    threadPool.awaitTermination(1, TimeUnit.HOURS);
}
Copy the code

In the test code, our thread pool had only one thread, we submitted five tasks, each task took 1 second to execute, and we used another timed task thread pool to switch the pauseable thread pool on and off. The running results are as follows:

Scheduled task thread pool

In the previous test, we used the timed task thread pool. Here we do another test. Let’s test the difference between scheduleAtFixedRate and scheduleWithFixedDelay. In the following code, we run two separate tests:

  • Once the task is executed at a fixed frequency, and once the task is executed with a fixed delay
  • Then close the scheduled task thread pool after 1 second (also through the scheduled task scheduling function)
  • The main thread waits until the thread pool terminates
@Test
public void test1(a) throws InterruptedException {
    AtomicInteger scheduleAtFixedRateTotal = new AtomicInteger();
    ScheduledExecutorService scheduleAtFixedRateExecutorService = Executors.newSingleThreadScheduledExecutor();
    ScheduledFuture scheduleAtFixedRateTotalFuture = scheduleAtFixedRateExecutorService.scheduleAtFixedRate(() -> {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("scheduleAtFixedRate:" + scheduleAtFixedRateTotal.incrementAndGet());
    }, 0.100, TimeUnit.MILLISECONDS);
    scheduleAtFixedRateExecutorService.schedule(() -> scheduleAtFixedRateTotalFuture.cancel(false), 1, TimeUnit.SECONDS);
    while(! scheduleAtFixedRateTotalFuture.isDone()) TimeUnit.MILLISECONDS.sleep(1);
    Assert.assertEquals(11, scheduleAtFixedRateTotal.get());

    AtomicInteger scheduleWithFixedDelayTotal = new AtomicInteger();
    ScheduledExecutorService scheduleWithFixedDelayExecutorService = Executors.newSingleThreadScheduledExecutor();
    ScheduledFuture scheduleWithFixedDelayFuture = scheduleWithFixedDelayExecutorService.scheduleWithFixedDelay(() -> {
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("scheduleWithFixedDelay:" + scheduleWithFixedDelayTotal.incrementAndGet());
    }, 0.100, TimeUnit.MILLISECONDS);
    scheduleWithFixedDelayExecutorService.schedule(() -> scheduleWithFixedDelayFuture.cancel(false), 1, TimeUnit.SECONDS);
    while(! scheduleWithFixedDelayFuture.isDone()) TimeUnit.MILLISECONDS.sleep(1);
    Assert.assertEquals(5, scheduleWithFixedDelayTotal.get());
}
Copy the code

We can also see from assertions that a fixed frequency of execution **” ignores “the execution time of the task, so it can be executed more times, resulting in 11 executions in a second. A task with fixed delay is executed at a fixed interval after the task is complete. The task can be executed only five times in about one second. Here is the output:

I’m putting double quotes around this, ignoring two words, because for a single-threaded timed task thread pool, if the task executes too slowly, slower than the frequency, then the thread pool doesn’t have the ability to execute at fixRate. Here you can try to change the sleep time from 100ms to 200ms, rerun the result is as follows:

Executors.newSingleThreadScheduledExecutor().schedule(() -> scheduleAtFixedRateTotalFuture.cancel(false), 1, TimeUnit.SECONDS);
Copy the code

(Or you can use a timed task thread pool of 2 threads.) As you can see, this time the result is as expected:

ForkJoin thread pool

Starting with Java 1.8, Executors provides newWorkStealingPool to get a ForkJoin thread pool. As you can see from the naming, this is a work-stealing thread pool. A traditional thread pool has a common queue of tasks, and more contention can occur when there are many, fast (CPU-intensive) tasks. ForkJoin has its own queue for each thread. You can steal tasks from other queues if there are no tasks on your own queue, ensuring throughput and reducing contention. Let’s write a code to compare:

@Slf4j
public class ForkJoinPoolBenchmark {
    @Test
    public void test(a) throws InterruptedException {
        AtomicLong atomicLong = new AtomicLong();
        StopWatch stopWatch = new StopWatch();
        ExecutorService normal = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        ExecutorService forkjoin = Executors.newWorkStealingPool(Runtime.getRuntime().availableProcessors());

        stopWatch.start("normal");
        LongStream.rangeClosed(1.10000000).forEach(__->normal.submit(atomicLong::incrementAndGet));
        normal.shutdown();
        normal.awaitTermination(1, TimeUnit.HOURS);
        stopWatch.stop();
        long r = atomicLong.get();
        stopWatch.start("forkjoin");
        LongStream.rangeClosed(1.10000000).forEach(__->forkjoin.submit(atomicLong::incrementAndGet));
        forkjoin.shutdown();
        forkjoin.awaitTermination(1, TimeUnit.HOURS);
        stopWatch.stop();
        log.info(stopWatch.prettyPrint());
        log.info("result:{},{}", r, atomicLong.get()); }}Copy the code

In this case, our task is simply to keep ++ an AtomicLong. The test results are as follows:

What happens if a thread pool task gets an exception?

It is often found that some friends write code, after the task is submitted to the thread pool, the task often exceptions, no matter the exception, they say nothing, the thread pool will catch the exception. Is it really so? Try writing some code:

@Slf4j
public class ThreadPoolExceptionTest {

    @Before
    public void setDefaultUncaughtExceptionHandler(a){
        Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e)->{
            log.warn("Exception in thread {}", t,e);
        });
    }

    @Test
    public void test(a) throws InterruptedException {
        String prefix = "test";
        ExecutorService threadPool = Executors.newFixedThreadPool(1.new ThreadFactoryImpl(prefix));
        IntStream.rangeClosed(1.10).forEach(i -> threadPool.execute(() -> {
            if (i == 5) throw new RuntimeException("error");
            log.info("I'm done : {}", i);
            if (i < 5) Assert.assertEquals(prefix + "1", Thread.currentThread().getName());
            else Assert.assertEquals(prefix + "2", Thread.currentThread().getName());
        }));

        threadPool.shutdown();
        threadPool.awaitTermination(1, TimeUnit.HOURS); }}Copy the code

Here we have 10 tasks in total, and on the fifth task, we actively throw an exception. The test1 thread will execute the following tasks because of the exception:

  • A task in the thread pool has an unhandled exception, which is ultimately an unhandled exception and can be handled by an unhandled exception
  • The thread terminates instead of the legendary thread pool catching the exception
  • The thread pool can only recreate new exceptions to fill the void, which comes at a cost

This is not entirely true. Let’s try changing execute to submit:

@Test
public void test(a) throws InterruptedException {
    String prefix = "test";
    ExecutorService threadPool = Executors.newFixedThreadPool(1.new ThreadFactoryImpl(prefix));
    List<Future> futures = new ArrayList<>();
    IntStream.rangeClosed(1.10).forEach(i -> futures.add(threadPool.submit(() -> {
        if (i == 5) throw new RuntimeException("error");
        log.info("I'm done : {}", i);
// if (i < 5) Assert.assertEquals(prefix + "1", Thread.currentThread().getName());
// else Assert.assertEquals(prefix + "2", Thread.currentThread().getName());
    })));

    for (Future future : futures) {
        try {
            future.get();
        } catch (ExecutionException e) {
            log.warn("future ExecutionException",e);
        }
    }
    threadPool.shutdown();
    threadPool.awaitTermination(1, TimeUnit.HOURS);
}
Copy the code

The following output is displayed:

@Test
public void test2(a) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();
    ExecutorService threadPool1 = Executors.newFixedThreadPool(1);
    stopWatch.start("execute");
    IntStream.rangeClosed(1.100000).forEach(i->threadPool1.execute(()->{
        throw new RuntimeException("error");
    }));
    threadPool1.shutdown();
    threadPool1.awaitTermination(1, TimeUnit.HOURS);
    stopWatch.stop();
    ExecutorService threadPool2 = Executors.newFixedThreadPool(1);
    stopWatch.start("submit");
    IntStream.rangeClosed(1.100000).forEach(i->threadPool2.submit(()->{
        throw new RuntimeException("error");
    }));
    threadPool2.shutdown();
    threadPool2.awaitTermination(1, TimeUnit.HOURS);
    stopWatch.stop();
    log.info(stopWatch.prettyPrint());
}
Copy the code

The results are as follows:

code

All the code for this article is at my Github Repo: github.com/JosephZhu19… The code is tested based on JDK11

conclusion

In this article, we did about a dozen experiments, each testing thread pools. The following points are summarized:

  • Thread pools are best created manually, rather than using what the system calls predefined common thread pools

  • In extreme cases, you may need to modify the behavior of the default thread pool to create threads

  • Note that the task recommendations in the thread pool do not have unhandled exceptions

  • Task execution using a scheduled task thread pool Note the size of the thread pool