• 【基础】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
    从系统安全角度出发,原则上都应该自己手动创建线程池
  • 相关阅读:
    win10 + Debian9.1双系统安装笔记
    高效查看MySQL帮助文档的方法 (转)
    初涉Delphi Socket编程
    Delphi xe5 StyleBook的用法(待续)
    Delphi xe5如何使用Bluestacks模拟器(用真机或者用猩猩,夜神模拟器,自带的不好用)
    Delphi xe5 控件TIdhttp的用法post,get解决中文乱码问题
    如何解析DELPHI XE5服务器返回的JSON数据(翻译)及中文乱码
    解决tomcat占用8080端口
    逆地址解析协议
    前后端分离
  • 原文地址:https://www.cnblogs.com/zendwang/p/threadpoolexecutor.html
Copyright © 2020-2023  润新知