线程池常见问题总结

创建方式

  • 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;
    }
  • Executor(不推荐)

原因:本质还是ThreadPoolExecutor

  • FixedThreadPool 和 SingleThreadExecutor : 使用的是无界的 LinkedBlockingQueue,任务队列最大长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致 OOM

  • CachedThreadPool :使用的是同步队列 SynchronousQueue, 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致 OOM

  • ScheduledThreadPool 和 SingleThreadScheduledExecutor : 使用的无界的延迟阻塞队列DelayedWorkQueue,任务队列最大长度为 Integer.MAX_VALUE,可能堆积大量的请求,从而导致 OOM

工作方式

  1. 线程在有任务的时候会创建核心线程数corePoolSize

  1. 当线程满了(有任务但是线程被使用完)不会立即扩容,而是放到阻塞队列中,当阻塞队列满了之后才会继续创建线程。

  1. 如果队列满了,线程数达到最大线程数则会执行拒绝策略

  1. 当线程数大于核心线程数时,超过KeepAliveTime(闲置时间),线程会被回收,最终会保持corePoolSize个线程。

拒绝策略

  • ThreadPoolExecutor.AbortPolicy: 抛出 RejectedExecutionException来拒绝新任务的处理。

  • ThreadPoolExecutor.CallerRunsPolicy: 调用执行自己的线程运行任务,也就是直接在调用execute方法的线程中运行(run)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果可以承受此延迟并且要求任何一个任务请求都要被执行,可以选择此策略。

  • ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。

  • ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。

应用场景

最大线程池大小

CPU 密集型任务(N+1): 利用 CPU 计算能力的任务

I/O 密集型任务(2N): 网络读取,文件读取

Future & Callable

Future:将任务交给子线程执行,Future<TASK>

FutureTask实现了 Future接口,可传入 Callable 或者 Runnable 对象

CompletableFuture:解决了Future一些局限性比如不支持异步任务的编排组合、获取计算结果的 get() 方法为阻塞调用等,主要是靠CompletionStage接口里面维护的大量函数式编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值