线程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?

简介: 线程池:第四章:ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别?

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";
    }
相关文章
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
9月前
|
Java 调度
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
当我们创建一个`ThreadPoolExecutor`的时候,你是否会好奇🤔,它到底发生了什么?比如:我传的拒绝策略、线程工厂是啥时候被使用的? 核心线程数是个啥?最大线程数和它又有什么关系?线程池,它是怎么调度,我们传入的线程?...不要着急,小手手点上关注、点赞、收藏。主播马上从源码的角度带你们探索神秘线程池的世界...
444 0
【源码】【Java并发】【线程池】邀请您从0-1阅读ThreadPoolExecutor源码
|
Dubbo Java 应用服务中间件
剖析Tomcat线程池与JDK线程池的区别和联系!
剖析Tomcat线程池与JDK线程池的区别和联系!
483 0
剖析Tomcat线程池与JDK线程池的区别和联系!
|
NoSQL 网络协议 Unix
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
1)Redis 属于单线程还是多线程?不同版本之间有什么区别?
317 2
WK
|
并行计算 调度 Python
GIL和线程之间的区别是什么
全局解释器锁(GIL)与线程在Python中具有不同角色。GIL作为CPython中的互斥锁,确保同一时间只有一个线程执行Python字节码,简化内存管理但限制多线程并行性;线程则是程序执行的最小单位,允许多个任务并发运行。GIL影响整个解释器,使多线程串行化;线程则代表独立执行流,受GIL制约。GIL在计算密集型任务中成为瓶颈,但在I/O密集型任务中多线程仍可提升性能。理解两者差异有助于优化多线程应用。
WK
121 1
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
368 0
【多线程面试题十】、说一说notify()、notifyAll()的区别
notify()唤醒单个等待对象锁的线程,而notifyAll()唤醒所有等待该对象锁的线程,使它们进入就绪队列竞争锁。
|
监控 Java
ThreadPoolExecutor 线程执行超时,释放线程
ThreadPoolExecutor 线程执行超时,释放线程
418 1
|
Java Spring 容器
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
1058 3
|
消息中间件 安全 数据处理
Python中的并发编程:理解多线程与多进程的区别与应用
在Python编程中,理解并发编程是提高程序性能和响应速度的关键。本文将深入探讨多线程和多进程的区别、适用场景及实际应用,帮助开发者更好地利用Python进行并发编程。

热门文章

最新文章