关于线程池参数的解释:
我这样设置,同时运行的线程数为什么大于maximumPoolSize,不应该只有一个线程同时运行吗?
THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
1,
1,
60,
TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<>(1),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
执行方法:
private static void testThreadPoolExecutor() {
THREAD_POOL_EXECUTOR.execute(() -> {
System.out.println("线程1");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
THREAD_POOL_EXECUTOR.submit(() -> {
System.out.println("线程2");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
THREAD_POOL_EXECUTOR.execute(() -> {
System.out.println("线程3");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
THREAD_POOL_EXECUTOR.execute(() -> {
System.out.println("线程4");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
THREAD_POOL_EXECUTOR.execute(() -> {
System.out.println("线程5");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
THREAD_POOL_EXECUTOR.shutdown();
}
结果,同时运行了两个线程(总是比maximumPoolSize大1),为什么不是一个
首先,看一下你这个五个
线程$n
,实际上称之为任务
更合适。线程1
直接创建一个线程来执行线程2
进入队列这两个是没有问题的。
然后,看
线程3
,这个时候,线程数
和队列
都达到最大了,使用reject
策略。CallerRunsPolicy
:直接在
当前线程
执行run
方法。这里
又多了一个线程
,就是执行这段代码的线程,可能就是你的主线程
。这就是为什么有
两个线程
的原因。后续的
线程4
和线程5
会在线程池线程
和当前线程
这两个线程中运行 。如果你使用了
AbortPolicy
策略,在线程3
时,就直接报异常了:同样的,由于
线程1
要执行3秒
,后续的线程4
和线程5
都会直接抛出异常。当然,你要处理这个异常,要不然,程序就中断了。等
线程1
执行结束,执行队列中的线程2
。