java 線程池 ThreadPoolExecutor
使用線程池的好處:
- 降低資源消耗
- 提高響應速度
- 提高線程的可管理性
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadPoolExecutor.CallerRunsPolicy());
-
CORE_POOL_SIZE
:核心線程數 -
MAX_POOL_SIZE
:最大線程數 -
KEEP_ALIVE_TIME
:等待時間 -
TimeUnit.SECONDS
:等待時間的單位 -
new ArrayBlockingQueue<>(QUEUE_CAPACITY)
:任務隊列爲 ArrayBlockingQueue ,容量爲 100 -
new ThreadPoolExecutor.CallerRunsPolicy()
:飽和策略爲 CallerRunsPolicy①:ThreadPoolExecutor.AbortPolicy:拋出 RejectedExecutionException來拒絕新任務的處理。
②:ThreadPoolExecutor.CallerRunsPolicy:調用並執行自己的線程以運行任務,即直接在調用execute方法的線程中運行(run)被拒絕的任務。如果執行程序已關閉,則替換任務。
③:ThreadPoolExecutor.DiscardPolicy:不處理新任務,直接丟棄掉。
④:ThreadPoolExecutor.DiscardOldestPolicy: 丟棄最早的未處理的任務請求。
ThreadPoolExecutor提供了幾種方法,通過它們我們可以找到執行程序的當前狀態,池大小,活動線程數和任務數。
public class MyRunnable implements Runnable {
private ThreadPoolExecutor executor;
private int seconds;
public MyRunnable(ThreadPoolExecutor executor, int delay)
{
this.executor = executor;
this.seconds=delay;
}
@Override
public void run()
{
System.out.println(
String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s, Thread:%d",
this.executor.getPoolSize(),
this.executor.getCorePoolSize(),
this.executor.getActiveCount(),
this.executor.getCompletedTaskCount(),
this.executor.getTaskCount(),
this.executor.isShutdown(),
this.executor.isTerminated(),
this.seconds
));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
這是使用ThreadPoolExecutor實現線程池的示例。
public class Test {
private static final int CORE_POOL_SIZE = 5;
private static final int MAX_POOL_SIZE = 10;
private static final int QUEUE_CAPACITY = 100;
private static final int KEEP_ALIVE_TIME = 10;
public static void main(String args[]){
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
new ThreadPoolExecutor.CallerRunsPolicy()
);
//將工作提交到線程池
for(int i=0; i<10; i++){
executorPool.execute(new MyRunnable(executorPool, i));
}
//終止線程池
executorPool.shutdown();
while (!executorPool.isTerminated()) {
}
System.out.println("finish!");
}
}
這是上面演示的輸出。
[monitor] [4/5] Active: 5, Completed: 0, Task: 10, isShutdown: true, isTerminated: false, Thread:0
[monitor] [5/5] Active: 5, Completed: 0, Task: 10, isShutdown: true, isTerminated: false, Thread:1
[monitor] [5/5] Active: 5, Completed: 0, Task: 10, isShutdown: true, isTerminated: false, Thread:4
[monitor] [5/5] Active: 5, Completed: 0, Task: 10, isShutdown: true, isTerminated: false, Thread:3
[monitor] [5/5] Active: 5, Completed: 0, Task: 10, isShutdown: true, isTerminated: false, Thread:2
[monitor] [5/5] Active: 4, Completed: 3, Task: 10, isShutdown: true, isTerminated: false, Thread:6
[monitor] [5/5] Active: 5, Completed: 3, Task: 10, isShutdown: true, isTerminated: false, Thread:7
[monitor] [5/5] Active: 3, Completed: 3, Task: 10, isShutdown: true, isTerminated: false, Thread:5
[monitor] [5/5] Active: 4, Completed: 5, Task: 9, isShutdown: true, isTerminated: false, Thread:8
[monitor] [5/5] Active: 5, Completed: 5, Task: 10, isShutdown: true, isTerminated: false, Thread:9
finish!