ThreadPoolExecutor共4個構造方法:java
直接看參數最多的7個參數分別表明:spa
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
1.當池中正在運行的線程數(包括空閒線程數)小於corePoolSize時,新建線程執行任務線程
public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1)); // 任務1 pool.execute(() -> { try { Thread.sleep(3 * 1000); System.out.println("--helloWorld_001--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); //任務2 pool.execute(() -> System.out.println("--helloWorld_002--" + Thread.currentThread().getName())); }
結論:線程1 結束後 沒有繼續線程1 而是啓動線程2code
2.當池中正在運行的線程數(包括空閒線程數)大於等於corePoolSize時,新插入的任務進入workQueue排隊(若是workQueue長度容許),等待空閒線程來執行。blog
public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1)); // 任務1 pool.execute(() -> { try { Thread.sleep(3 * 1000); System.out.println("--helloWorld_001--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務2 pool.execute(() -> { try { Thread.sleep(5 * 1000); System.out.println("--helloWorld_002--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務3 pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName())); }
結論:任務2在運行過程當中,任務3啓動不會新建線程,由於有一個隊列是空的,maximumPoolSize=3這個參數不起做用。隊列
3.當隊列裏的任務達到上限,而且池中正在進行的線程小於maxinumPoolSize,對於新加入的任務,新建線程。get
public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1)); // 任務1 pool.execute(() -> { try { Thread.sleep(3 * 1000); System.out.println("--helloWorld_001--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務2 pool.execute(() -> { try { Thread.sleep(5 * 1000); System.out.println("--helloWorld_002--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務3 pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName())); // 任務4 pool.execute(() -> System.out.println("--helloWorld_004--" + Thread.currentThread().getName())); }
結果:任務1,2啓動後 任務3在隊列 ,隊列就滿了,因爲正在進行的線程數是2<maximumPoolSize,只能新建一個線程了 而後任務4就進了新線程-3,任務4結束,隊列裏的任務3在線程3 進行。it
4.隊列裏的任務達到上限,而且池中正在運行的線程等於maximumPoolSize,對於新加入的任務,執行拒絕策略(線程池默認的策略是拋異常)。io
public static void main(String[] args) { ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1)); // 任務1 pool.execute(() -> { try { Thread.sleep(3 * 1000); System.out.println("--helloWorld_001--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務2 pool.execute(() -> { try { Thread.sleep(5 * 1000); System.out.println("--helloWorld_002--" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 任務3 pool.execute(() -> System.out.println("--helloWorld_003--" + Thread.currentThread().getName())); // 任務4 pool.execute(() -> { try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("--helloWorld_004--" + Thread.currentThread().getName()); }); // 任務5 pool.execute(() -> System.out.println("--helloWorld_005--" + Thread.currentThread().getName())); }
運行結果: Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task ExecutorDemo$$Lambda$5/999966131@7699a589 rejected from java.util.concurrent.ThreadPoolExecutor@58372a00[Running, pool size = 3, active threads = 3, queued tasks = 1, completed tasks = 0] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063) at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379) at ExecutorDemo.main(ExecutorDemo.java:40) --helloWorld_004----pool-1-thread-3 --helloWorld_003--pool-1-thread-3 --helloWorld_001--pool-1-thread-1 --helloWorld_002--pool-1-thread-2
結論:隊列達到上限,線程池達到最大值,故拋出異常。class
分爲兩種方式:
pool.shutdown();//平緩關閉,不容許新的線程加入,正在運行的都跑完便可關閉。
pool.shutdownNow();//暴力關閉。不容許新的線程加入,且直接停到正在進行的線程。