• ThreadPoolExecutor 线程池参数详解,执行流程


    线程池的使用:

    1. public static void main(String[] args) {
    2. ThreadFactory sThreadFactory = new ThreadFactory() {
    3. private final AtomicInteger mCount = new AtomicInteger(1);
    4. @Override
    5. public Thread newThread(Runnable r) {
    6. int andIncrement = mCount.getAndIncrement();
    7. return new Thread(r, "Thread # " + andIncrement);
    8. }
    9. };
    10. Runnable runnable = new Runnable() {
    11. @Override
    12. public void run() {
    13. try {
    14. Thread.sleep(1000);
    15. System.out.println(Thread.currentThread().getName() + "完成任务");
    16. } catch (InterruptedException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. };
    21. ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10,
    22. 200L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(1), sThreadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
    23. for (int i = 0; i < 200; i++) {
    24. threadPoolExecutor.execute(runnable);
    25. }
    26. }

    运行后:


    ThreadPoolExecutor构造函数详解:

    1. public ThreadPoolExecutor(int corePoolSize,
    2. int maximumPoolSize,
    3. long keepAliveTime,
    4. TimeUnit unit,
    5. BlockingQueue workQueue,
    6. ThreadFactory threadFactory,
    7. RejectedExecutionHandler handler)

     corePoolSize:核心线程数,也就是这个线程池一创建就自带多少个线程

    maximumPoolSize:最大线程数,就是这个线程池最多能容纳多少个线程

    keepAliveTime:设置线程空闲了多长时间后被回收

    unit :第三个参数的时间单位

    workQueue:设置加入的任务多过corePoolSize时加入的阻塞队列

    threadFactory:线程工厂。一般来说就是给线程改个名

    handler:拒绝策略。当加入的任务太多,线程池和阻塞队列都塞满的情况下该怎么办

    拒绝策略可选:

    ThreadPoolExecutor.AbortPolicy:直接抛出异常

    ThreadPoolExecutor.CallerRunsPolicy:让调用线程池的自己执行任务

    ThreadPoolExecutor.DiscardOldestPolicy删除老任务,让新任务进来(渣男行为)

    ThreadPoolExecutor.DiscardPolicy:删除新任务(中国好男人)


    线程池的执行过程:(以我这个例子为例)

    创建一个线程池,自带2个线程,最多装10个线程,线程空闲200毫秒才会被回收,阻塞队列就只能放一个任务,当线程池和阻塞队列都满了的情况下抛弃老任务去执行新任务。

    在for循环里一下子塞入200个任务,最终结果是执行了11个任务

    注:这里的阻塞队列只能放一个任务的原因是,当阻塞队列满了后线程池才会去创建额外的线程,否则阻塞队列还没满的情况下,执行的线程数一直都是2(核心线程数)。这里我设置一个是作为测试使用,一般是不会这么干的

  • 相关阅读:
    Java数据结构之二叉树的构建与遍历
    OpenGL之坐标系以及单位
    【mfc/VS2022】计图实验:绘图工具设计知识笔记
    【实战详解】如何快速搭建接口自动化测试框架?Python + Requests
    MyBatis之ResultMap的association和collection标签详解
    请求本地的 JSON 文件作为 mock 数据
    asp.net docker-compose添加网关和网关配置
    Vuex状态刷新状态丢失的处理方法
    互联网Java工程师面试题·Spring篇·第二弹
    一文了解JVM(中)
  • 原文地址:https://blog.csdn.net/weixin_47592544/article/details/127977032