1. 程式人生 > >java中執行緒池ExecutorService 執行緒管理

java中執行緒池ExecutorService 執行緒管理

 程式碼:

package com.bob.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorServiceTest {
	 static void run(ExecutorService threadPool){
		for(int i=1 ; i < 5; i++ ){
			final int taskId = i;
			threadPool.execute(new Runnable(){

				@Override
				public void run() {
					for(int i = 1; i < 5; i++){
						try {
							Thread.sleep(20);
						} catch (Exception e) {
							e.printStackTrace();
						}
						System.out.println("第"+taskId+"次任務的第"+i+"次執行");
					}
				}
				
			});
		}
		threadPool.shutdown(); // 任務執行完畢,關閉執行緒池 
	}
	public static void main(String args[]){
		// 建立可以容納3個執行緒的執行緒池 
		ExecutorService fixExecutorService = Executors.newFixedThreadPool(3);
		
		// 執行緒池的大小會根據執行的任務數動態分配
		ExecutorService cachedExecutorService = Executors.newCachedThreadPool();
		
		// 建立單個執行緒的執行緒池,如果當前執行緒在執行任務時突然中斷,則會建立一個新的執行緒替代它繼續執行任務
		ExecutorService singleExecutorService = Executors.newSingleThreadExecutor();
		
		// 效果類似於Timer定時器
		ExecutorService scheduleExecutorService = Executors.newScheduledThreadPool(3);
		
		run(fixExecutorService);
//		run(cachedExecutorService);
//		run(singleExecutorService);
//		run(scheduleExecutorService);
		
	}

}

CachedThreadPool

CachedThreadPool會建立一個快取區,將初始化的執行緒快取起來。會終止並且從快取中移除已有60秒未被使用的執行緒。

如果執行緒有可用的,就使用之前建立好的執行緒,

如果執行緒沒有可用的,就新建立執行緒。

  • 重用:快取型池子,先檢視池中有沒有以前建立的執行緒,如果有,就reuse;如果沒有,就建一個新的執行緒加入池中
  • 使用場景:快取型池子通常用於執行一些生存期很短的非同步型任務,因此在一些面向連線的daemon型SERVER中用得不多。
  • 超時:能reuse的執行緒,必須是timeout IDLE內的池中執行緒,預設timeout是60s,超過這個IDLE時長,執行緒例項將被終止及移出池。
  • 結束:注意,放入CachedThreadPool的執行緒不必擔心其結束,超過TIMEOUT不活動,其會自動被終止。
  1. // 執行緒池的大小會根據執行的任務數動態分配
  2. ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
  3. publicstatic ExecutorService newCachedThreadPool() {  
  4.     returnnew ThreadPoolExecutor(0,                 //core pool size
  5.                                   Integer.MAX_VALUE, //maximum pool size
  6.                                   60L,               //keep alive time
  7.                                   TimeUnit.SECONDS,  
  8.                                   new SynchronousQueue<Runnable>());  
  9. }  

執行結果:
  1. 第1次任務的第1次執行  
  2. 第4次任務的第1次執行  
  3. 第3次任務的第1次執行  
  4. 第2次任務的第1次執行  
  5. 第3次任務的第2次執行  
  6. 第4次任務的第2次執行  
  7. 第2次任務的第2次執行  
  8. 第1次任務的第2次執行  
  9. 第2次任務的第3次執行  
  10. 第4次任務的第3次執行  
  11. 第3次任務的第3次執行  
  12. 第1次任務的第3次執行  
  13. 第2次任務的第4次執行  
  14. 第1次任務的第4次執行  
  15. 第3次任務的第4次執行  
  16. 第4次任務的第4次執行  

4個任務是交替執行的

FixedThreadPool

在FixedThreadPool中,有一個固定大小的池。

如果當前需要執行的任務超過池大小,那麼多出的任務處於等待狀態,直到有空閒下來的執行緒執行任務,

如果當前需要執行的任務小於池大小,空閒的執行緒也不會去銷燬。

  • 重用:fixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時建新的執行緒
  • 固定數目:其獨特之處在於,任意時間點,最多隻能有固定數目的活動執行緒存在,此時如果有新的執行緒要建立,只能放在另外的佇列中等待,直到當前的執行緒中某個執行緒終止直接被移出池子
  • 超時:和cacheThreadPool不同,FixedThreadPool沒有IDLE機制(可能也有,但既然文件沒提,肯定非常長,類似依賴上層的TCP或UDP IDLE機制之類的),
  • 使用場景:所以FixedThreadPool多數針對一些很穩定很固定的正規併發執行緒,多用於伺服器
  • 原始碼分析:從方法的原始碼看,cache池和fixed 池呼叫的是同一個底層池,只不過引數不同:
    fixed池執行緒數固定,並且是0秒IDLE(無IDLE)
    cache池執行緒數支援0-Integer.MAX_VALUE(顯然完全沒考慮主機的資源承受能力),60秒IDLE
  1. // 建立可以容納3個執行緒的執行緒池
  2. ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  
  3. publicstatic ExecutorService newFixedThreadPool(int nThreads) {  
  4.         returnnew ThreadPoolExecutor(nThreads, //core pool size
  5.                                       nThreads, //maximum pool size
  6.                                       0L,       //keep alive time
  7.                                       TimeUnit.MILLISECONDS,  
  8.                                       new LinkedBlockingQueue<Runnable>());  
  9. }  

執行結果:
  1. 第1次任務的第1次執行  
  2. 第3次任務的第1次執行  
  3. 第2次任務的第1次執行  
  4. 第3次任務的第2次執行  
  5. 第2次任務的第2次執行  
  6. 第1次任務的第2次執行  
  7. 第3次任務的第3次執行  
  8. 第1次任務的第3次執行  
  9. 第2次任務的第3次執行  
  10. 第3次任務的第4次執行  
  11. 第1次任務的第4次執行  
  12. 第2次任務的第4次執行  
  13. 第4次任務的第1次執行  
  14. 第4次任務的第2次執行  
  15. 第4次任務的第3次執行  
  16. 第4次任務的第4次執行  

建立了一個固定大小的執行緒池,容量為3,然後迴圈執行了4個任務。由輸出結果可以看到,前3個任務首先執行完,然後空閒下來的執行緒去執行第4個任務

SingleThreadExecutor 

SingleThreadExecutor得到的是一個單個的執行緒,這個執行緒會保證你的任務執行完成。

如果當前執行緒意外終止,會建立一個新執行緒繼續執行任務,這和我們直接建立執行緒不同,也和newFixedThreadPool(1)不同。

  1. // 建立單個執行緒的執行緒池,如果當前執行緒在執行任務時突然中斷,則會建立一個新的執行緒替代它繼續執行任務  
  2. ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();  
  3. publicstatic ExecutorService newSingleThreadExecutor() {  
  4.         returnnew FinalizableDelegatedExecutorService  
  5.             (new ThreadPoolExecutor(1,  //core pool size
  6.                                     1,  //maximum pool size
  7.                                     0L, //keep alive time
  8.                                     TimeUnit.MILLISECONDS,  
  9.                                     new LinkedBlockingQueue<Runnable>()));  
  10. }  

執行結果:

  1. 第1次任務的第1次執行  
  2. 第1次任務的第2次執行  
  3. 第1次任務的第3次執行  
  4. 第1次任務的第4次執行  
  5. 第2次任務的第1次執行  
  6. 第2次任務的第2次執行  
  7. 第2次任務的第3次執行  
  8. 第2次任務的第4次執行  
  9. 第3次任務的第1次執行  
  10. 第3次任務的第2次執行  
  11. 第3次任務的第3次執行  
  12. 第3次任務的第4次執行  
  13. 第4次任務的第1次執行  
  14. 第4次任務的第2次執行  
  15. 第4次任務的第3次執行  
  16. 第4次任務的第4次執行  

4個任務是順序執行的


ScheduledThreadPool

ScheduledThreadPool是一個固定大小的執行緒池,與FixedThreadPool類似,執行的任務是定時執行

  1. // 效果類似於Timer定時器
  2. ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);  
  3. public ScheduledThreadPoolExecutor(int corePoolSize) {  
  4.         super(corePoolSize,      //core pool size
  5.               Integer.MAX_VALUE, //maximum pool size
  6.               0,                 //keep alive time
  7.               TimeUnit.NANOSECONDS,  
  8.               new DelayedWorkQueue());  
  9. }  

執行結果:
  1. 第1次任務的第1次執行  
  2. 第2次任務的第1次執行  
  3. 第3次任務的第1次執行  
  4. 第2次任務的第2次執行  
  5. 第1次任務的第2次執行  
  6. 第3次任務的第2次執行  
  7. 第2次任務的第3次執行  
  8. 第1次任務的第3次執行  
  9. 第3次任務的第3次執行  
  10. 第2次任務的第4次執行  
  11. 第1次任務的第4次執行  
  12. 第3次任務的第4次執行  
  13. 第4次任務的第1次執行  
  14. 第4次任務的第2次執行  
  15. 第4次任務的第3次執行  
  16. 第4次任務的第4次執行  
此處,未看出與FixedThreadPool的區別.

相關推薦

java執行ExecutorService 執行管理

 程式碼: package com.bob.test; import java.util.concurrent.ExecutorService; import java.util.concurren

在spring boot使用java執行ExecutorService

1. 認識java執行緒池 1.1 在什麼情況下使用執行緒池? 1.單個任務處理的時間比較短 2.需處理的任務的數量大 1.2 使用執行緒池的好處: 1.減少在建立和銷燬執行緒上所花的時間以及系統資源的開銷 2.如不使用執行緒池,有可能造成系統建立大量執行緒而導致消耗完系統記

java 執行 ExecutorService shutdonw及其多執行執行完成判斷

1.線上程池 ExecutorService的使用過程中,主執行緒開啟了多個子執行緒,如果判斷所有子執行緒任務是否完成問題; 方法一: BusinessHandler b = new Busines

java 執行 ExecutorService相關歸納

public class ExecutorServiceDemo {     public static void main(String[] args) {          // 單執行緒池  &

Java執行ExecutorService

開篇前,我們先來看看不使用執行緒池的情況: new Thread的弊端 執行一個非同步任務你還只是如下new Thread嗎? ?1234567new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated meth

java常見的四種執行的區別

在使用執行緒時,可以這樣建立一個執行緒池: ExecutorService executorService= Executors.newCachedThreadPool(); executorService.execute(()-> System.out.println("run ..

Java執行 ExecutorService

一、ExecutorService介紹 ExecutorService是Java中對執行緒池定義的一個介面,它java.util.concurrent包中,在這個介面中定義了和後臺任務執行相關的方法:  Java API對ExecutorService

Java執行(1)----執行基礎知識和CachedThreadPool

本文探討一下java中的執行緒池 首先,什麼是執行緒池? 執行緒池通過多個任務重用執行緒,執行緒建立的開銷就被分攤到了多個任務上,而且請求到達時執行緒已經存在,消除了等待執行緒建立帶來的延遲,使得程式

Java執行ExecutorService時讓主執行等待子執行完成後繼續處理

(() -> { try { System.out.println(finalI + " 我執行了。。。"); Thread.sleep(5000L);

Java執行ExecutorService 的理解與使用

介面 java.util.concurrent.ExecutorService 表述了非同步執行的機制,並且可以讓任務在後臺執行。一個 ExecutorService 例項因此特別像一個執行緒池。事實上,在 java.util.concurrent 包中的 Ex

Java執行ExecutorService方法詳解

執行緒在專案中有時候是很重要的一部分,對於那些不需要返回結果只需呼叫而且執行之間較長的方法,可考慮用執行緒實現。但是執行緒的頻繁建立和銷燬會降低系統的效能,因此多執行緒情況下最好要考慮執行緒池技術。 執行緒池的多種建立方式下一節介紹。 建立執行緒池方式: //建立可快

執行ExecutorService 併發數的(引入訊號量Semaphore)控制執行

檢視本機處理器的核心數程式碼:Runtime.getRuntime().availableProcessors() 所以,應用程式的最小執行緒數應該等於可用的處理器核數。如果所有的任務都是計算密集型的,則建立處理器可用的核心數那麼多執行緒就可以了。在這種情況下

Java執行-55-ExecutorService執行

前面介紹了執行緒組,其實還有比執行緒組更大的管理執行緒的單元,叫執行緒池。字面意思就是一個池子裡,放著很多執行緒,就叫執行緒池。現在我們手機APP訪問任何的伺服器,伺服器上都是採用執行緒池來管理執行緒。我們知道,在記憶體中新建執行緒是需要耗費記憶體,如果沒有執行緒池,很多執行緒隨著使用者訪問而建

JAVA執行ExecutorService四種模式的建立、使用及區別

ExecutorService ExecutorService是Java中對執行緒池定義的一個介面,它java.util.concurrent包中。Java API對ExecutorService介面的實現有兩個(ThreadPoolExecutor和Schedule

Java使用訊息佇列還是直接使用執行ExecutorService非同步處理?

說說這兩種的區別,各自適合什麼場景? 用執行緒池ExecutorService非同步處理:我理解ExecutorService其實也是內部使用了佇列(如LinkedBlockingQueue),所以從設計上,其實和使用中間價的訊息佇列是差不多一致的。只是這裡應用伺服器既

Java執行 ExecutorService( [ɪgˈzekjətə(r)] ) 的運用

一,執行緒池工具類 package demo.util; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 執行緒池工具類(單例模式) *

java常用的五種執行的實現

package com.superb.juint_thread; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.

Java常用的四種執行

在Java中使用執行緒池,可以用ThreadPoolExecutor的建構函式直接創建出執行緒池例項,如何使用參見之前的文章Java執行緒池構造引數詳解。不過,在Executors類中,為我們提供了常用執行緒池的建立方法。接下來我們就來了解常用的四種: newFixedThreadPool 首先,看一下這種執

關於執行 ExecutorService 的總結

一 、Java通過Executors提供四種執行緒池: newCachedThreadPool建立一個可快取執行緒池,如果執行緒池長度超過處理需要,可靈活回收空閒執行緒,若無可回收,則新建執行緒。 newFixedThreadPool 建立一個定長執行緒池,可控制執行緒最大併發數,超

執行原理–執行ExecutorService

文章目錄 執行緒池原理–執行器ExecutorService 相關方法 shutdown submit 批量提交任務 執行緒池原理–總索引 執行緒池原理–執行器Exe