和我以前的Spring系列文章同样,咱们会以作一些Demo作实验的方式来复习一些知识点。 本文咱们先从Java并发中最最经常使用的线程池开始。java
首先咱们写一个方法来每秒一次定时输出线程池的基本信息:git
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);
}
复制代码
而后,咱们写一个方法来定时提交任务到线程池:github
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);
});
});
}
复制代码
能够看到:缓存
如今咱们写一个最普通的线程池,而且等待线程池全部任务执行完成:tomcat
@Test
public void test1() 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);
}
复制代码
能够看到,这个线程池是:bash
对于这样的配置,你们想一下,任务提交过去后,线程池的工做方式是怎么样的?抛出几个问题:多线程
咱们执行后观察一下输出:并发
09:51:37.709 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:37.715 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0
09:51:37.718 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 0
09:51:37.718 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:37.718 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 0
09:51:37.718 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:38.705 [pool-2-thread-1] INFO 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.705 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 0
09:51:38.705 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:38.705 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 0
09:51:38.705 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:38.716 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 1 started
09:51:39.701 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:39.701 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 1
09:51:39.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 1
09:51:39.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:39.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 0
09:51:39.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:39.718 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 2 started
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 0
09:51:40.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:41.701 [pool-2-thread-1] INFO 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.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:41.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:41.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 1
09:51:41.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:42.702 [pool-2-thread-1] INFO 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.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:42.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:42.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 2
09:51:42.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:43.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:43.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:43.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 3
09:51:43.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:44.701 [pool-2-thread-1] INFO 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.701 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:44.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:44.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 4
09:51:44.702 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:45.702 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:45.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:45.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 5
09:51:45.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:46.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:46.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:46.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 6
09:51:46.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:47.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:47.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:47.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 7
09:51:47.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:48.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:48.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
09:51:48.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 8
09:51:48.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:48.719 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 1 finished
09:51:48.719 [pool-1-thread-1] 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 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2
09:51:49.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:49.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 1
09:51:49.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 8
09:51:49.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:49.720 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 2 finished
09:51:49.720 [pool-1-thread-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 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2
09:51:50.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:50.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:50.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 8
09:51:50.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:51.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:51.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:51.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 9
09:51:51.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:52.703 [pool-2-thread-1] INFO 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.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
09:51:52.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:52.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 10
09:51:52.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:52.749 [pool-1-thread-3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 15 started
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 3
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 3
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 10
09:51:53.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:53.754 [pool-1-thread-4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 16 started
09:51:54.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:54.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 4
09:51:54.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 4
09:51:54.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:54.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 10
09:51:54.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:54.755 [pool-1-thread-5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 17 started
09:51:55.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
09:51:55.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
09:51:55.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
09:51:55.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
09:51:55.703 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in queue: 10
09:51:55.704 [pool-2-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.FrameworkMethod$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.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$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)
复制代码
经过输出能够看到:app
咱们知道,Java的线程池默认状况下是更倾向于使用队列来存听任务而不是倾向于使用更多的线程来消化任务,只有当队列满了以后才会使用更多的线程池临时处理一下突发的任务增多。 有的时候,咱们其实更但愿的是更激进的方式,线程池优先开启更多的线程,而是把队列当成一个后备方案来使用。好比咱们这个例子,任务执行的很慢,须要10s,每秒提交一个任务,若是线程池能够弹性到5个最大线程,那么20秒后有5个任务在执行,5个任务已经完成,还有10个在线程池里,这些任务最终均可以完成,而不是像以前由于线程池过晚扩张致使慢任务来不及处理。less
咱们能够经过Hack的方式来实现:
@Test
public void test2() 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);
}
复制代码
实现这个功能主要依靠两个地方的改进:
咱们来看一下输出:
10:53:37.889 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:37.898 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 0
10:53:37.901 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 0
10:53:37.901 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:37.901 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:37.901 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:38.879 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 0
10:53:38.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:38.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:38.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:38.919 [elastic-pool1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 1 started
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 1
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 1
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:39.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:39.924 [elastic-pool2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 2 started
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:40.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:40.930 [elastic-pool3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 3 started
10:53:41.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:41.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 3
10:53:41.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 3
10:53:41.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:41.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:41.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:41.934 [elastic-pool4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 4 started
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 4
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 4
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:42.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:42.935 [elastic-pool5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 5 started
10:53:43.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:43.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:43.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:43.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:43.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:53:43.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:44.881 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:44.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:44.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 1
10:53:44.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:45.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:45.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:45.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 2
10:53:45.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:46.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:46.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:46.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 3
10:53:46.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:47.880 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:47.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:47.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 4
10:53:47.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:48.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:48.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 0
10:53:48.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:48.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:49.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:49.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 1
10:53:49.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:49.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:50.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:50.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 2
10:53:50.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:50.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:51.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:51.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 3
10:53:51.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:51.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:52.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:52.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 4
10:53:52.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:52.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:53.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:53.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:53.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:53:53.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:54.880 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:54.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:54.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 6
10:53:54.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:55.880 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:55.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:55.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 7
10:53:55.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:56.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:56.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:56.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 8
10:53:56.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:57.881 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:57.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:57.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 9
10:53:57.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:53:58.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:58.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 5
10:53:58.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 10
10:53:58.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:53:59.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:53:59.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 6
10:53:59.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 9
10:53:59.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:00.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:00.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 7
10:54:00.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 8
10:54:00.883 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:01.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:01.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 8
10:54:01.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 7
10:54:01.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:02.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:02.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 9
10:54:02.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 6
10:54:02.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:03.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:03.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:03.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:03.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:04.878 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:04.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:04.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:04.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:05.878 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:05.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:05.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:05.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:06.881 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:06.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:06.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:06.881 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:07.881 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:07.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:07.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:07.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:08.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:08.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 10
10:54:08.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 5
10:54:08.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:09.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:09.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 11
10:54:09.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 4
10:54:09.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:10.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:10.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 12
10:54:10.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 3
10:54:10.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:11.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:11.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 13
10:54:11.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 2
10:54:11.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:12.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:12.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 14
10:54:12.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 1
10:54:12.882 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.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.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 5
10:54:13.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:13.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:13.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:13.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:14.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:14.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:14.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:14.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:15.878 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:15.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:15.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:15.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:16.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:16.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:16.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:16.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:17.878 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:17.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:17.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:17.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:18.877 [pool-1-thread-1] 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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 5
10:54:18.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 15
10:54:18.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:18.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:18.929 [elastic-pool1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 16 finished
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 4
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 4
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 16
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:19.880 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:19.938 [elastic-pool2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 17 finished
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 3
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 3
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 17
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:20.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:20.947 [elastic-pool3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 18 finished
10:54:21.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:21.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 2
10:54:21.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 2
10:54:21.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 18
10:54:21.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:21.879 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:21.943 [elastic-pool4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 19 finished
10:54:22.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:22.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Pool Size: 1
10:54:22.877 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Active Threads: 1
10:54:22.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks Completed: 19
10:54:22.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - Number of Tasks in Queue: 0
10:54:22.878 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - =========================
10:54:22.950 [elastic-pool5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.ThreadPoolExecutorTest - 20 finished
复制代码
从这个结果能够看到:
其实,这里还能够想到另外一种思路,既然咱们但愿在高并发的状况下,线程池可以更积极建立线程,那么咱们还能够初始化线程池的时候就初始化5个核心线程,5个最大线程,而后开启核心线程回收,这样也能够在并发低的时候节约线程。
固然这里的这个实现很是简单粗暴,其实何时队列返回false是一种学问,咱们最好有必定的缓冲,不行的话再建立新的线程,也不必定就像这里的直接返回false,后面咱们会提到tomcat线程池更好的实现。
在以前的测试中咱们使用到了一个自定义的线程工厂类来为线程命名:
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);
return thread;
}
}
复制代码
这是一个很是好的实践,对于复杂的项目必定有N多个线程池,有了明确的容易识别的命名,更容易在出现问题的时候进行排查。
Tomcat线程池基于原生线程池作了一些改进,主要在三方面:
下面看下相关代码: 首先是队列这块,咱们重点关注下重写的offer方法,返回false来增长线程的时机:
@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);
}
复制代码
而后是线程池这块,咱们重点注意出现拒绝异常后的处理策略:
@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() {
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 new RejectedExecutionException(x);
}
} else {
submittedCount.decrementAndGet();
throw rx;
}
}
}
private static class RejectHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor executor) {
throw new RejectedExecutionException();
}
}
}
复制代码
如今来写一段测试代码:
@Slf4j
public class TomcatThreadPoolTest {
@Test
public void test() 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() {
log.info("Start:{}", name);
if (slow) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info("Finish:{}", name);
}
}
}
复制代码
在测试代码中,咱们的队列只有5,咱们的最大线程也是5,而咱们的慢任务是10个,由于咱们的任务容许等待1050ms尝试提交到队列,因此基于这样的配置,咱们的快任务也能顺利执行完成,而不会出错:
16:38:36.117 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - submit<=pool, getPoolSize: 2, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-1)
16:38:36.165 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-1
16:38:36.166 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - submit<=pool, getPoolSize: 2, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-2)
16:38:36.166 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-2
16:38:36.166 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 2, getMaximumPoolSize:5
16:38:36.166 [pool-1-thread-3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-3
16:38:36.166 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 3, getMaximumPoolSize:5
16:38:36.167 [pool-1-thread-4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-4
16:38:36.167 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - Grow thread pool, getPoolSize: 4, getMaximumPoolSize:5
16:38:36.167 [pool-1-thread-5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-5
16:38:36.168 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-6)
16:38:36.168 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-7)
16:38:36.168 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-8)
16:38:36.169 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-9)
16:38:36.169 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=true, name=slow-10)
16:38:36.170 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false, name=quick-1)
16:38:37.169 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-2
16:38:37.169 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-1
16:38:37.169 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-7
16:38:37.169 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-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.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false, name=quick-3)
16:38:37.170 [pool-1-thread-4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-4
16:38:37.170 [pool-1-thread-3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-3
16:38:37.170 [pool-1-thread-5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-5
16:38:37.170 [pool-1-thread-4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-8
16:38:37.170 [main] WARN me.josephzhu.javaconcurrenttest.concurrent.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:slow-10
16:38:37.170 [pool-1-thread-3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:slow-9
16:38:37.171 [main] 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.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.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false, name=quick-6)
16:38:38.171 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-7
16:38:38.171 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-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.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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-1
16:38:38.172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-2
16:38:38.172 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-3
16:38:38.172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-4
16:38:38.172 [pool-1-thread-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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-5
16:38:38.172 [main] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatTaskQueue - pool==max, getPoolSize: 5, getMaximumPoolSize:5, task:TomcatThreadPoolTest.Task(slow=false, name=quick-7)
16:38:38.172 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-6
16:38:38.172 [pool-1-thread-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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-7
16:38:38.172 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:quick-7
16:38:38.172 [main] 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 [pool-1-thread-2] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-8
16:38:38.173 [pool-1-thread-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 [pool-1-thread-1] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Start:quick-9
16:38:38.173 [pool-1-thread-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 [pool-1-thread-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 [pool-1-thread-4] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-8
16:38:38.175 [pool-1-thread-3] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-9
16:38:38.175 [pool-1-thread-5] INFO me.josephzhu.javaconcurrenttest.concurrent.executors.TomcatThreadPoolTest - Finish:slow-10
复制代码
注意日志中出现了好几回RejectedExecutionException,可是通过等待任务都提交到了队列中。
咱们看看Executors预约义的两种所谓经常使用的线程池:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
复制代码
所谓固定大小的线程池就是线程大小固定,可是队列是无界的。显然,若是任务很是多很是慢超过了线程池的处理能力,产生了堆积,那么这个无界队列可能会致使OOM这是一个风险:
还有一种所谓缓存线程池,这个缓存意思是线程是缓存着用的,60秒回收,须要的话就建立,线程数量无上限,须要的话会一直建立。这个也很极端,可能会建立过多线程,一样会致使OOM:
测试代码就不给出了,你能够本身作实验。 因此阿里Java开发手册不建议使用这两种预约义的线程池,咱们应该本身根据须要控制线程池的:
这里咱们给出官方的例子,经过实现自定义的beforeExecute来实现可暂停的线程池。
线程池代码以下:
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() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}
复制代码
写一段测试代码试试:
@Test
public void test() 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);
}
复制代码
在测试代码中,咱们的线程池只有一个线程,咱们提交五个任务进去,每个任务须要执行1秒,咱们使用另外一个定时任务线程池来定时开关这个可暂停的线程池。运行结果以下:
在刚才的测试中,咱们用到了定时任务线程池,这里咱们再作一个测试。 咱们来测试一下scheduleAtFixedRate和scheduleWithFixedDelay的区别。 在下面的代码里,咱们分别进行两次测试:
@Test
public void test1() 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());
}
复制代码
经过断言咱们也能够知道,固定频率执行任务**"忽略"**了任务执行的时间,因此能执行更屡次数,最终在1秒执行了11次。固定延迟执行任务是在任务完成后再延迟固定的间隔去执行,最终只能在1秒左右的时间执行5次。 下面是输出:
在这里,忽略两个字,我打上了双引号,那是由于对于单线程的定时任务线程池,任务若是执行太慢,比频率还慢,那么线程池也没这个能力去fixRate执行。这里你能够尝试一下把休眠时间100ms修改成200ms,从新运行后结果以下:
Executors.newSingleThreadScheduledExecutor().schedule(() -> scheduleAtFixedRateTotalFuture.cancel(false), 1, TimeUnit.SECONDS);
复制代码
(或者也可使用2个线程的定时任务线程池) 能够看到,此次的结果符合预期:
从Java 1.8开始,Executors提供了newWorkStealingPool来得到一个ForkJoin线程池。 从命名能够看到,这是一个工做窃取线程池,传统的线程池具备公共的一个任务队列,在任务不少,任务执行很快(CPU密集型任务)的状况下,会发生比较多的竞争问题,而ForkJoin的话每个线程都有本身的任务队列,若是本身的队列没有任务的话能够从其它队列窃取任务,这样确保了吞吐的同时,减小了竞争。咱们写一段代码来比较一下:
@Slf4j
public class ForkJoinPoolBenchmark {
@Test
public void test() 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());
}
}
复制代码
在这里,咱们的任务很简单就是不断++一个AtomicLong。测试结果以下:
常常发现有一些小伙伴写代码,在把任务提交到线程池后,任务常常会出异常,出异常也无论,他们说没事,线程池会捕获异常的。真的是这样吗?写段代码试试:
@Slf4j
public class ThreadPoolExceptionTest {
@Before
public void setDefaultUncaughtExceptionHandler(){
Thread.setDefaultUncaughtExceptionHandler((Thread t, Throwable e)->{
log.warn("Exception in thread {}", t,e);
});
}
@Test
public void test() 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);
}
}
复制代码
在这里咱们一共有10个任务,执行到第五个任务的时候,会主动抛出一个异常。 从断言能够看到,一开始的任务是在test1线程上执行的,由于出了异常后面的任务就在test2线程上执行了,看看运行结果:
不过这个结论不彻底正确,咱们尝试把execute改成submit来试试:
@Test
public void test() 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);
}
复制代码
输出结果以下:
@Test
public void test2() 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());
}
复制代码
结果以下:
本文的全部代码见个人Github Repo:github.com/JosephZhu19… 代码的测试基于JDK11
本文咱们作了十来个实验,各类测试线程池。总结下来几点:
线程池最好手动建立,不要用系统所谓的预约义的经常使用线程池
在极端状况下可能须要修改默认线程池建立线程的行为
注意线程池中的任务建议仍是不要出现未处理异常为好
使用定时任务线程池进行任务执行注意线程池大小问题