如果你對ThreadPoolExecutor的執行還不瞭解,可以參考有界、無界隊列對ThreadPoolExcutor執行的影響這篇文章。
在ThreadPoolExecutor類中有個allowCoreThreadTimeOut(boolean value)方法,該方法用來設置是否回收在保活時間後依然沒沒有任務執行核心線程。
下面通過程序來驗證該參數的設置,如果你對CountDownLatch不瞭解,可以參考 併發工具類:等待多線程完成的CountDownLatch,和join的區別
public class PoolThreadRecycling {
private static final int CORE_POOL_SIZE = 5;
private static final int MAX_POOL_SIZE = 10;
private static final int QUEUE_CAPACITY = 1;
private static final Long KEEP_ALIVE_TIME = 1L;
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
new ThreadPoolExecutor.CallerRunsPolicy());
static {
//如果設置爲true,當任務執行完後,所有的線程在指定的空閒時間後,poolSize會爲0
//如果不設置,或者設置爲false,那麼,poolSize會保留爲核心線程的數量
executor.allowCoreThreadTimeOut(true);
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 1; i <= 10; i++) {
executor.submit(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
System.out.println("poolSize:" + executor.getPoolSize());
System.out.println("core:" + executor.getCorePoolSize());
System.out.println("活躍:" + executor.getActiveCount());
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("開始檢測線程池中線程數量");
while (true) {
Thread.sleep(1000);
System.out.println("poolSize:" + executor.getPoolSize());
System.out.println("core:" + executor.getCorePoolSize());
System.out.println("活躍:" + executor.getActiveCount());
System.out.println("======");
}
}
}
代碼中的靜態代碼塊中通過executor.allowCoreThreadTimeOut(true);設置回收核心線程,執行結果如下:
poolSize:9
core:5
活躍:9
開始檢測線程池中線程數量
poolSize:1
core:5
活躍:0
======
poolSize:0
core:5
活躍:0
======
poolSize:0
core:5
活躍:0
======
可以看到,當設置爲ture時,線程池中的任務都執行完後,線程池中的線程數量是0,因爲核心線程也都被回收了。
如果將其設置爲false呢,執行結果如下
poolSize:9
core:5
活躍:9
開始檢測線程池中線程數量
poolSize:5
core:5
活躍:0
======
poolSize:5
core:5
活躍:0
======
線程池中的任務都執行完後,線程池中核心線程沒有被回收。
這個參數設置成true還是false需要根據你具體的業務判斷,如果該業務需要執行的次數並不多,採用多線程只是爲了縮短執行的時間,那麼可以設置成false,畢竟用完後很長時間纔會用到,線程乾耗着也是耗費資源的。但是如果是需要較高併發執行的業務,那麼可以設置爲true,保留着線程,避免每次都得創建線程耗費資源。