線程池:第四章: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";
        }