• 【基础】ThreadPoolExecutor


    7大核心参数
    1. corePoolSize
    2. maximumPoolSize
    3. keepAliveTime
    4. unit
    5. workQueue
    6. threadFactory
    7. RejectedExecutionHandler

    线程池执行流程图

    4种拒绝策略
    1. AbortPolicy (不干还发火)
      直接抛出拒绝异常(继承自RuntimeException),会中断调用者的处理过程,所以除非有明确需求,一般不推荐
    2. CallerRunsPolicy(不做,我自己上)
      调用者线程中运行当前被丢弃的任务,如果线程池已经关闭了,则直接丢弃该任务
    3. DiscardOledestPolicy(看看排期,移除最前面的,任务继续)
      丢弃队列中最老的,然后再次尝试提交新任务。
    4. DiscardPolicy(不做,就丢)
      丢弃无法加载的任务。
    自定义拒绝策略
    1. netty自己实现的线程池里面私有的一个拒绝策略,单独启动一个新的临时线程来执行任务。
      private static final class NewThreadRunsPolicy implements RejectedExecutionHandler {
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                try {
                    final Thread t = new Thread(r, "Temporary task executor");
                    t.start();
                } catch (Throwable e) {
                    throw new RejectedExecutionException(
                            "Failed to start a new thread", e);
                }
            }
        }
    
    1. dubbo的一个例子,它直接继承的 AbortPolicy ,加强了日志输出,并且输出dump文件
    public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
    
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            String msg = String.format("Thread pool is EXHAUSTED!" +
                            " Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," +
                            " Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!",
                    threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(),
                    e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(),
                    url.getProtocol(), url.getIp(), url.getPort());
            logger.warn(msg);
            dumpJStack();
            throw new RejectedExecutionException(msg);
        }
    }
    
    
    JDK已封装好的线程池存在的潜在风险
    1. FixedThreadPool 和 SingleThreadPool:
      允许的请求队列长度为 Integer.MAX_VALUE ,会堆积大量请求OOM
    2. CachedThreadPool 和 ScheduledThreadPool:
      允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量线程OOM
    从系统安全角度出发,原则上都应该自己手动创建线程池
  • 相关阅读:
    用Python完成一个汇率转换器
    鸿蒙如何用JS开发智能手表App
    鸿蒙如何用JS开发智能手表App
    SAP Spartacus SplitViewComponent Migration 的一个具体例子
    SAP Spartacus B2B 页面 Popover Component 的条件显示逻辑
    SAP Spartacus 升级时关于 schematics 的更新
    SAP Spartacus B2B 页面 Disable 按钮的显示原理
    SAP Spartacus B2B 页面 Disable Confirmation 对话框的显示原理
    通过 Feature Level 动态控制 SAP Spartacus 的页面显示
    SAP Commerce Cloud Build Manifest Components
  • 原文地址:https://www.cnblogs.com/zendwang/p/threadpoolexecutor.html
Copyright © 2020-2023  润新知