1. 程式人生 > >Java使用執行緒池和執行緒工廠

Java使用執行緒池和執行緒工廠

package com.uno.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;

/**
 * 執行緒池測試
 * @author uno
 *	5:coreThreadCount:核心執行緒數,即前5個執行緒來了就建立執行緒,加入執行緒池
 *	10:maxthreadCount:最大執行緒數,當core滿時,會向workBlockQueue加入執行緒,等待執行
 *	new ArrayBlockingQueue(5):當blockqueue中滿,會根據maxThreadCount再建立加入執行緒池
 *	當maxThreadCount滿時,RejectedExecutionHandler拒絕策略上場
 *	shutdown:關閉執行緒池,等待快取佇列中執行緒執行完成
 *	shutdownNow:立即關閉執行緒池
 */

/**
 *  引用網上一段話
 *  1.當執行緒池小於corePoolSize時,新提交任務將建立一個新執行緒執行任務,即使此時執行緒池中存在空閒執行緒。 
	2.當執行緒池達到corePoolSize時,新提交任務將被放入workQueue中,等待執行緒池中任務排程執行 
	3.當workQueue已滿,且maximumPoolSize>corePoolSize時,新提交任務會建立新執行緒執行任務 
	4.當提交任務數超過maximumPoolSize時,新提交任務由RejectedExecutionHandler處理 
	5.當執行緒池中超過corePoolSize執行緒,空閒時間達到keepAliveTime時,關閉空閒執行緒 
	6.當設定allowCoreThreadTimeOut(true)時,執行緒池中corePoolSize執行緒空閒時間達到keepAliveTime也將關閉
 * @author uno
 *
 */
public class ThreadPool {

	private static ThreadPoolExecutor executor = null;
	static {
		executor = new ThreadPoolExecutor(5, 10, 200, 
				TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5), new MyTaskThreadFactory(), new AbortPolicy()
				);
		executor.prestartCoreThread(); //預啟動一個執行緒
//		executor.prestartAllCoreThreads();//預啟動corePoolSize個執行緒到執行緒池
	}
	
	
	public static void main(String[] args) {
		System.out.println("執行緒池執行緒數: "+executor.getPoolSize());
		for(int i = 0; i<15;i++){
			System.out.println(executor.isShutdown());
			executor.execute(new MyTask(i, "uno執行緒:"+i));
			System.out.println("執行緒池執行緒數: "+executor.getPoolSize());
			System.out.println("阻塞佇列中執行緒數:" + executor.getQueue().size());
			System.out.println("已執行完執行緒數:" + executor.getCompletedTaskCount());
		}
		executor.shutdown(); //關閉執行緒池
	}
	
	
}
/**
 * 自定義執行緒工廠
 * @author uno
 * 
 */
class MyTaskThreadFactory implements ThreadFactory{
	private static String FACTORYNAME = "MYTASKFACTORY";
	private static List<? super Thread> threadList = new ArrayList<>();
	
	public void setFactoryName(String name){
		FACTORYNAME = name;
	}
	@Override
	public Thread newThread(Runnable r) {
		synchronized (r) {
			//這裡可以自定義個Thread,用了處理在建立執行緒前後預處理
			Thread t = new Thread(r, FACTORYNAME + threadList.size());
			threadList.add(t);
			return t;
		}
	}
}
/**
 * 任務執行緒類
 * @author uno
 * 區別於執行緒工廠建立的執行緒:執行緒工廠建立的執行緒是用來執行任務執行緒(MyTask)的執行緒
 */
class MyTask extends Thread {
	private int num;
	public MyTask(int i, String name) {
		super(name);
		this.num = i;
	}
	@Override
	public void run() {
		try {
			System.out.println(this.getName() + ", 正執行task " + num);
			Thread.sleep(2000);
		} catch (Exception e) {
		}
		System.out.println(this.getName() + ", task " + num + " 執行完成");
	}
}



輸出結果:

執行緒池執行緒數: 1
false
執行緒池執行緒數: 2
阻塞佇列中執行緒數:0
執行緒0, 正執行task 0
已執行完執行緒數:0
false
執行緒池執行緒數: 3
阻塞佇列中執行緒數:0
執行緒1, 正執行task 1
已執行完執行緒數:0
false
執行緒池執行緒數: 4
阻塞佇列中執行緒數:0
執行緒2, 正執行task 2
已執行完執行緒數:0
false
執行緒池執行緒數: 5
阻塞佇列中執行緒數:0
已執行完執行緒數:0
false
執行緒3, 正執行task 3
執行緒池執行緒數: 5
阻塞佇列中執行緒數:0
已執行完執行緒數:0
false
執行緒4, 正執行task 4
執行緒池執行緒數: 5
阻塞佇列中執行緒數:1
已執行完執行緒數:0
false
執行緒池執行緒數: 5
阻塞佇列中執行緒數:2
已執行完執行緒數:0
false
執行緒池執行緒數: 5
阻塞佇列中執行緒數:3
已執行完執行緒數:0
false
執行緒池執行緒數: 5
阻塞佇列中執行緒數:4
已執行完執行緒數:0
false
執行緒池執行緒數: 5
阻塞佇列中執行緒數:5
已執行完執行緒數:0
false
執行緒池執行緒數: 6
阻塞佇列中執行緒數:5
執行緒10, 正執行task 10
已執行完執行緒數:0
false
執行緒池執行緒數: 7
阻塞佇列中執行緒數:5
已執行完執行緒數:0
false
執行緒11, 正執行task 11
執行緒池執行緒數: 8
阻塞佇列中執行緒數:5
已執行完執行緒數:0
false
執行緒12, 正執行task 12
執行緒池執行緒數: 9
阻塞佇列中執行緒數:5
已執行完執行緒數:0
false
執行緒13, 正執行task 13
執行緒池執行緒數: 10
阻塞佇列中執行緒數:5
已執行完執行緒數:0
執行緒14, 正執行task 14
執行緒0, task 0 執行完成
執行緒3, task 3 執行完成
執行緒2, task 2 執行完成
執行緒1, task 1 執行完成
執行緒7, 正執行task 7
執行緒6, 正執行task 6
執行緒10, task 10 執行完成
執行緒5, 正執行task 5
執行緒9, 正執行task 9
執行緒4, task 4 執行完成
執行緒11, task 11 執行完成
執行緒12, task 12 執行完成
執行緒8, 正執行task 8
執行緒14, task 14 執行完成
執行緒13, task 13 執行完成
執行緒7, task 7 執行完成
執行緒9, task 9 執行完成
執行緒5, task 5 執行完成
執行緒6, task 6 執行完成
執行緒8, task 8 執行完成
正好印證了上面的

 1.當執行緒池小於corePoolSize時,新提交任務將建立一個新執行緒執行任務,即使此時執行緒池中存在空閒執行緒。 
2.當執行緒池達到corePoolSize時,新提交任務將被放入workQueue中,等待執行緒池中任務排程執行 
3.當workQueue已滿,且maximumPoolSize>corePoolSize時,新提交任務會建立新執行緒執行任務 
4.當提交任務數超過maximumPoolSize時,新提交任務由RejectedExecutionHandler處理 
5.當執行緒池中超過corePoolSize執行緒,空閒時間達到keepAliveTime時,關閉空閒執行緒 
6.當設定allowCoreThreadTimeOut(true)時,執行緒池中corePoolSize執行緒空閒時間達到keepAliveTime也將關閉