Java使用默认线程池的陷阱问题

我们都知道JDK1.5之后提供了ThreadPoolExecutor类,可以用来自定义线程池。

线程池有很多好处,比如:

减少资源消耗,避免频繁创建和销毁线程,可以直接复用已有线程。
提供速度,任务来了之后,因为线程已经存在,可以直接使用。
提高线程的可管理性。线程是非常宝贵的资源。如果创建的线程过多,不仅会消耗系统资源,甚至会影响系统的稳定性。
使用线程池,可以非常方便地创建、管理和监控线程。
该类包含许多静态方法:

newCachedThreadPool: 创建一个可缓冲线程。如果线程池的大小超过处理需要,可以灵活回收空闲线程。如果没有回收,则创建一个新线程。
newFixedThreadPool:创建一个固定大小的线程池。如果任务数量超过线程池大小,则将多余的任务放入队列中。
newScheduledThreadPool:创建一个固定大小的线程池,可以执行定时的周期性任务。
newSingleThreadExecutor:创建一个只有一个线程的线程池,保证所有任务按顺序安装和执行。
在高并发场景下,如果使用这些静态方法来创建线程池,会出现一些问题。

那么,让我们看看存在哪些问题。

newFixedThreadPool:允许请求的队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM。
newSingleThreadExecutor:请求允许的队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM。
newCachedThreadPool: 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量线程,导致OOM。
那么我们应该怎么做呢?

建议先使用ThreadPoolExecutor类,我们自定义线程池。

具体代码如下:

ExecutorService threadPool = <b>new</b> ThreadPoolExecutor(
    8, <font><i>//The number of core threads in the corePoolSize thread pool</i></font><font>
    10, </font><font><i>//maximumPoolSize The maximum number of threads in the thread pool</i></font><font>
    60, </font><font><i>//The maximum idle time of threads in the thread pool, after which idle threads will be recycled</i></font><font>
    TimeUnit.SECONDS,</font><font><i>//time unit</i></font><font>
    <b>new</b> ArrayBlockingQueue(500), </font><font><i>//queue</i></font><font>
    <b>new</b> ThreadPoolExecutor.CallerRunsPolicy()); </font><font><i>//rejection policy</i></font><font>
</font>

顺便说一句,如果是一些低并发的场景,使用Executors类创建线程池也不是不行,也不是所有场景都可以使用。

在这些低并发场景中,很难出现OOM问题,所以我们需要根据实际业务场景进行选择。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值