ThreadPoolExecutor參數詳解

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {

1、corePoolSize —new ThreadPoolExecutor的時候創建的的線程,
如果ThreadPoolExecutor.execute的任務數>corePoolSize 則會把任務放到BlockingQueue 、如果BlockingQueue滿了會繼續創建新線程、一直到線程個數大於第二個參數maximumPoolSize
2、maximumPoolSize 允許創建的最大線程數、如果BlockingQueue已經滿了、線程數==maximumPoolSize 則會執行ThreadPoolExecutor的拒絕策略
3、keepAliveTime 如果BlockingQueue從滿了到未滿、則大於corePoolSize, 小於maximumPoolSize的線程, 會在keepAliveTime的時間內存活、否則會被回收


參考
https://my.oschina.net/u/2250599/blog/498787

一、使用Executors創建線程池
之前創建線程的時候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()這三個方法。當然Executors也是用不同的參數去new ThreadPoolExecutor

1. newFixedThreadPool()

創建線程數固定大小的線程池。 由於使用了LinkedBlockingQueue所以maximumPoolSize 沒用,當corePoolSize滿了之後就加入到LinkedBlockingQueue隊列中。每當某個線程執行完成之後就從LinkedBlockingQueue隊列中取一個。所以這個是創建固定大小的線程池。

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
2.newSingleThreadPool()

創建線程數爲1的線程池,由於使用了LinkedBlockingQueue所以maximumPoolSize 沒用,corePoolSize爲1表示線程數大小爲1,滿了就放入隊列中,執行完了就從隊列取一個。

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}

3.newCachedThreadPool()

創建可緩衝的線程池。沒有大小限制。由於corePoolSize爲0所以任務會放入SynchronousQueue隊列中,SynchronousQueue只能存放大小爲1,所以會立刻新起線程,由於maxumumPoolSize爲Integer.MAX_VALUE所以可以認爲大小爲2147483647。受內存大小限制。

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

二、使用ThreadPoolExecutor創建線程池
ThreadPoolExecutor的構造函數
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
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核心線程數大小,當線程數<corePoolSize ,會創建線程執行runnable

    2、maximumPoolSize 最大線程數, 當線程數 >= corePoolSize的時候,會把runnable放入workQueue中

    3、keepAliveTime  保持存活時間,當線程數大於corePoolSize的空閒線程能保持的最大時間。

    4、unit 時間單位

    5、workQueue 保存任務的阻塞隊列

    6、threadFactory 創建線程的工廠

    7、handler 拒絕策略

任務執行順序:
1、當線程數小於corePoolSize時,創建線程執行任務。

    2、當線程數大於等於corePoolSize並且workQueue沒有滿時,放入workQueue中

    3、線程數大於等於corePoolSize並且當workQueue滿時,新任務新建線程運行,線程總數要小於maximumPoolSize

    4、當線程總數等於maximumPoolSize並且workQueue滿了的時候執行handler的rejectedExecution。也就是拒絕策略。

ThreadPoolExecutor默認有四個拒絕策略:
1、ThreadPoolExecutor.AbortPolicy() 直接拋出異常RejectedExecutionException

    2、ThreadPoolExecutor.CallerRunsPolicy()    直接調用run方法並且阻塞執行

    3、ThreadPoolExecutor.DiscardPolicy()   直接丟棄後來的任務

    4、ThreadPoolExecutor.DiscardOldestPolicy()  丟棄在隊列中隊首的任務

當然可以自己繼承RejectedExecutionHandler來寫拒絕策略.

int corePoolSize = 1;
int maximumPoolSize = 2;
int keepAliveTime = 10;
// BlockingQueue workQueue = new LinkedBlockingQueue();
BlockingQueue workQueue = new ArrayBlockingQueue(5);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
//線程池和隊列滿了之後的處理方式
//1.跑出異常
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
RejectedExecutionHandler handler2 = new ThreadPoolExecutor.CallerRunsPolicy();
RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardPolicy();
RejectedExecutionHandler handler4 = new ThreadPoolExecutor.DiscardOldestPolicy();

	ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler2);
	
	
	for (int j = 1; j < 15; j++) {
		threadPoolExecutor.execute(new Runnable() {
			
			public void run() {
				
				try {
					System.out.println(Thread.currentThread().getName());
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				
			}
		});
	}
	
	System.out.println(threadPoolExecutor);
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章