ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。
ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。
看看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:线程池维护线程的最小数量.
int maximumPoolSize:线程池维护线程的最大数量.
long keepAliveTime:空闲线程的存活时间.
TimeUnit unit: 时间单位,现有纳秒,微秒,毫秒,秒枚举值.
BlockingQueue<Runnable> workQueue:持有等待执行的任务队列.
ThreadFactory:线程工厂
RejectedExecutionHandler handler:用来拒绝一个任务的执行
而拒绝策略有四种:
(1)ThreadPoolExecutor.AbortPolicy策略,是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
(2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
(3)ThreadPoolExecutor.DiscardPolicy策略,不能执行的任务将被丢弃.
(4)ThreadPoolExecutor.DiscardOldestPolicy策略,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程).
上一章有详细讲解
那我们现在来用一用ThreadPoolTaskExecutor
弄一个工具类
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(); } /** * 使用线程池执行业务方法并加入视图 * @param tasks 计数器 * @param modelMap 视图 * @param modelName 视图名 * @param service 要调用的service * @param method 被调用的方法 * @param param 方法参数 */ 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 计数器 * @param modelMap 视图 * @param keyName 参数名 * @param service 要调用的service * @param method 被调用的方法 * @param param 方法参数 */ 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 *** 执行 ((( %s ))) 方法,耗时 <<< %s 秒 >>> 参数", 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(); } }
实战案例:
@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"); //剩下六个类似的业务。。。。 ............................... 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"; }