線程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何區(qū)別?
ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。
ThreadPoolTaskExecutor是對ThreadPoolExecutor進(jìn)行了封裝處理。
看看ThreadPoolTaskExecutor源碼
看看ThreadPoolExecutor源碼
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> 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;
}
int corePoolSize:線程池維護(hù)線程的最小數(shù)量.
int maximumPoolSize:線程池維護(hù)線程的最大數(shù)量.
long keepAliveTime:空閑線程的存活時(shí)間.
TimeUnit unit: 時(shí)間單位,現(xiàn)有納秒,微秒,毫秒,秒枚舉值.
BlockingQueue<Runnable> workQueue:持有等待執(zhí)行的任務(wù)隊(duì)列.
ThreadFactory:線程工廠
RejectedExecutionHandler handler:用來拒絕一個(gè)任務(wù)的執(zhí)行
而拒絕策略有四種:
(1)ThreadPoolExecutor.AbortPolicy策略,是默認(rèn)的策略,處理程序遭到拒絕將拋出運(yùn)行時(shí) RejectedExecutionException。
(2)ThreadPoolExecutor.CallerRunsPolicy策略 ,調(diào)用者的線程會執(zhí)行該任務(wù),如果執(zhí)行器已關(guān)閉,則丟棄.
(3)ThreadPoolExecutor.DiscardPolicy策略,不能執(zhí)行的任務(wù)將被丟棄.
(4)ThreadPoolExecutor.DiscardOldestPolicy策略,如果執(zhí)行程序尚未關(guān)閉,則位于工作隊(duì)列頭部的任務(wù)將被刪除,然后重試執(zhí)行程序(如果再次失敗,則重復(fù)此過程).
上一章有詳細(xì)講解
那我們現(xiàn)在來用一用ThreadPoolTaskExecutor
弄一個(gè)工具類
package utils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.ui.ModelMap;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
public class ThreadTool {
static ThreadPoolTaskExecutor threadPoolTaskExecutor;
static {
threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(5);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.setQueueCapacity(100);
threadPoolTaskExecutor.initialize();
}
/**
* 使用線程池執(zhí)行業(yè)務(wù)方法并加入視圖
* @param tasks 計(jì)數(shù)器
* @param modelMap 視圖
* @param modelName 視圖名
* @param service 要調(diào)用的service
* @param method 被調(diào)用的方法
* @param param 方法參數(shù)
*/
public static void runMethod(CountDownLatch tasks, ModelMap
modelMap, String modelName, Object service, Method method, Object...
param){
threadPoolTaskExecutor.submit(new RunInThreadPool(
tasks,modelMap,modelName,service,method,param));
}
}
RunInThreaddPool
package utils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
public class RunInThreadPool implements Runnable {
CountDownLatch countDownLatch;
Map modelMap;
String keyName;
Object service;
Method method;
Object[] param;
/**
* @param countDownLatch 計(jì)數(shù)器
* @param modelMap 視圖
* @param keyName 參數(shù)名
* @param service 要調(diào)用的service
* @param method 被調(diào)用的方法
* @param param 方法參數(shù)
*/
public RunInThreadPool(CountDownLatch countDownLatch, Map
modelMap, String keyName, Object service, Method method, Object...
param) {
this.countDownLatch = countDownLatch;
this.modelMap = modelMap;
this.keyName = keyName;
this.service = service;
this.method = method;
this.param = param;
}
@Override
public void run() {
Object result = null;
try {
Long start = System.currentTimeMillis();
result = method.invoke(service, param);
Long end = System.currentTimeMillis();
System.out.println(String.format("%s *** 執(zhí)行 ((( %s ))) 方法,耗時(shí) <<< %s 秒 >>> 參數(shù)",
service.getClass(),
method.getName(),
(end - start),
JsonUtils.toJson(param)));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
modelMap.put(keyName, result);
countDownLatch.countDown();
}
}
實(shí)戰(zhàn)案例:
@RequestMapping("/goodsDetail")
public String goodsDetail(GoodsBean goodsBean, PageBean pageBean, ModelMap modelMap) throws Exception {
final CountDownLatch latch = new CountDownLatch(7);
Method getRelatedGoods = goodsService.getClass().getMethod("getRelatedGoods", GoodsBean.class, String.class);
getRelatedGoods.setAccessible(Boolean.TRUE);
ThreadTool.runMethod(latch , modelMap, "relatedGoods0", goodsService, getRelatedGoods, goodsBean, "0");
//剩下六個(gè)類似的業(yè)務(wù)。。。。
...............................
latch.await();
return "production/index";
}
對比:
@RequestMapping("/getRelatedGoods")
@AppController
public String getRelatedGoods(GoodsBean goodsBean, String show_type,ModelMap modelMap) {
modelMap.addAttribute("getRelatedGoods",goodsService.getRelatedGoods(goodsBean, show_type));
return "production/index";
}