【程式設計開發】日式 AVG——我那悽慘無比的 NVL 探索經歷
阿新 • • 發佈:2022-01-29
ThreadPoolExecutor提供了四個構造方法:
我們以最後一個構造方法(引數最多的那個),對其引數進行解釋:
public ThreadPoolExecutor(int corePoolSize, // 1 int maximumPoolSize, // 2 long keepAliveTime, // 3 TimeUnit unit, // 4 BlockingQueue<Runnable> workQueue, // 5 ThreadFactory threadFactory, // 6 RejectedExecutionHandler handler ) { //7 if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
序號 | 名稱 | 型別 | 含義 |
---|---|---|---|
1 | corePoolSize | int | 核心執行緒池大小 |
2 | maximumPoolSize | int | 最大執行緒池大小 |
3 | keepAliveTime | long | 執行緒最大空閒時間 |
4 | unit | TimeUnit | 時間單位 |
5 | workQueue | BlockingQueue<Runnable> | 執行緒等待佇列 |
6 | threadFactory | ThreadFactory | 執行緒建立工廠 |
7 | handler | RejectedExecutionHandler | 拒絕策略 |
自定義執行緒池:
public class ThreadPoolTest { public static void main(String[] args) throws IOException { int corePoolSize = 2;// 核心執行緒大小 int maximumPoolSize = 4;// 最大執行緒池大小 long keepAliveTime = 10; // 執行緒空閒10s後自動結束 TimeUnit unit = TimeUnit.SECONDS; // ArrayBlockingQueue,該阻塞佇列底層維護了一個定長陣列(建立物件必須指定容量) BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2); ThreadFactory threadFactory = new NameTreadFactory();// 自定義執行緒工廠 RejectedExecutionHandler handler = new MyIgnorePolicy(); // 自定義拒絕策略 // handler = new ThreadPoolExecutor.AbortPolicy();// 無法處理新任務會丟擲RejectedExecutionException異常 // 建立執行緒池物件 ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); executor.prestartAllCoreThreads(); // 預啟動所有核心執行緒 // 建立10個任務物件提交到執行緒池中 for (int i = 1; i <= 10; i++) { MyTask task = new MyTask(String.valueOf(i)); executor.execute(task); } System.in.read(); //阻塞主執行緒 } // 任務物件 static class MyTask implements Runnable { private String name; public MyTask(String name) { this.name = name; } @Override public void run() { try { System.out.println(this.toString() + " is running!"); Thread.sleep(3000); //讓任務執行慢點 } catch (InterruptedException e) { e.printStackTrace(); } } public String getName() { return name; } @Override public String toString() { return "MyTask [name=" + name + "]"; } } // 自定義拒絕策略 static class MyIgnorePolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { doLog(r, executor); } private void doLog(Runnable r, ThreadPoolExecutor e) { // 可做日誌記錄等 System.err.println(r.toString() + " rejected"); // System.out.println("completedTaskCount: " + e.getCompletedTaskCount()); } } // 執行緒工廠類 static class NameTreadFactory implements ThreadFactory { private final AtomicInteger mThreadNum = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement()); System.out.println(t.getName() + " has been created"); return t; } } }
輸出結果如下:
該執行緒池同一時間最多處理4個任務,2個任務處於等待對列中,其餘的任務都會被拒絕執行。
執行緒池的處理流程主要分為3步:
- 當在execute(Runnable)方法中提交的新任務後,執行緒池先判斷執行緒數是否達到了核心執行緒數(corePoolSize)。如果未達到執行緒數,則建立核心執行緒處理任務;否則,就執行下一步;
- 接著執行緒池判斷任務佇列是否滿了。如果沒滿,則將任務新增到任務佇列中;否則,執行下一步;
- 接著因為任務佇列滿了,執行緒池就判斷執行緒數是否達到了最大執行緒數。如果未達到,則建立非核心執行緒處理任務;否則,就執行飽和策略,預設會丟擲RejectedExecutionException異常。
setCorePoolSize
和setMaximumPoolSize
進行動態更改。