線程池ThreadPool簡單使用


 ThreadPoolExecutor可以用來創建線程池,例如:

1 ThreadPoolExecutor executor=new ThreadPoolExecutor(10,13,
2                 200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
ThreadPoolExecutor 構造函數為:
public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); 
}

其中各參數的含義:

corePoolSize

線程池啟動后,在池中保持的線程的最小數量。需要說明的是線程數量是逐步到達corePoolSize值的。例如corePoolSize被設置為10,而任務數量只有5,則線程池中最多會啟動5個線程,而不是一次性地啟動10個線程。

maxinumPoolSize

線程池中能容納的最大線程數量,如果超出,則使用RejectedExecutionHandler拒絕策略處理。

keepAliveTime

線程的最大生命周期。這里的生命周期有兩個約束條件:一:該參數針對的是超過corePoolSize數量的線程;二:處於非運行狀態的線程。舉個例子:如果corePoolSize(最小線程數)為10,maxinumPoolSize(最大線程數)為20,而此時線程池中有15個線程在運行,過了一段時間后,其中有3個線程處於等待狀態的時間超過keepAliveTime指定的時間,則結束這3個線程,此時線程池中則還有12個線程正在運行。

unit

這是keepAliveTime的時間單位,可以是納秒,毫秒,秒,分鍾等。

workQueue

任務隊列。當線程池中的線程都處於運行狀態,而此時任務數量繼續增加,則需要一個容器來容納這些任務,這就是任務隊列。這個任務隊列是一個阻塞式的單端隊列。

 

threadFactory

定義如何啟動一個線程,可以設置線程的名稱,並且可以確定是否是后台線程等。

handler

拒絕任務處理器。由於超出線程數量和隊列容量而對繼續增加的任務進行處理的程序。

 

具體實例:

 

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {

	public static void main(String[] args) {
		//如果Executors提供的三個靜態方法能滿足要求,就盡量使用它提供的三個方法,因為自己去手動配置ThreadPoolExecutor的參數有點麻煩,要根據實際任務的類型和數量來進行配置
		ThreadPoolExecutor executor=new ThreadPoolExecutor(10,13,
				200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
				for(int i=0;i<18;i++)
				{
				MyTask myTask=new MyTask(i);
				executor.execute(myTask);//提交線程
				System.out.println("線程池中的線程數目:"+executor.getPoolSize()+
				"隊列中等待執行的任務數目:"+executor.getQueue().size()+
				"已經執行完的任務數目:"+executor.getCompletedTaskCount());
				}
				executor.shutdown();//啟動有序關閉,
				}
}
		class MyTask implements Runnable {
			
				private int taskName;
				public MyTask(int num){
					this.taskName=num;
				}
				
				public void run(){
					System.out.println("正在執行:"+taskName);
					try
					{
					Thread.currentThread().sleep(4000);
					}
					catch(InterruptedException e)
					{
					e.printStackTrace();
					}
					System.out.println("task"+taskName+"執行完畢");
				}

		}

 

  不過在java doc中,並不提倡我們直接使用ThreadPoolExecutor,而是使用Executors類中提供的幾個靜態方法來創建線程池:

Executors.newCachedThreadPool();         //創建一個緩沖池,緩沖池容量大小為Integer.MAX_VALUE
Executors.newSingleThreadExecutor();    //創建容量為1的緩沖池
Executors.newFixedThreadPool( int );     //創建固定容量大小的緩沖池

從它們的具體實現來看,它們實際上也是調用了ThreadPoolExecutor,只不過參數都已配置好了。

  newFixedThreadPool創建的線程池corePoolSize和maximumPoolSize值是相等的,它使用的LinkedBlockingQueue;

  newSingleThreadExecutor將corePoolSize和maximumPoolSize都設置為1,也使用的LinkedBlockingQueue;

  newCachedThreadPool將corePoolSize設置為0,將maximumPoolSize設置為Integer.MAX_VALUE,使用的SynchronousQueue,也就是說來了任務就創建線程運行,當線程空閑超過60秒,就銷毀線程。

  實際中,如果Executors提供的三個靜態方法能滿足要求,就盡量使用它提供的三個方法,因為自己去手動配置ThreadPoolExecutor的參數有點麻煩,要根據實際任務的類型和數量來進行配置。

 

參考:https://www.cnblogs.com/dolphin0520/p/3932921.html

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM