返回

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

发布时间:2023-11-01 12:09:55 179

我们都知道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 = new ThreadPoolExecutor(
8, //The number of core threads in the corePoolSize thread pool
10,
//maximumPoolSize The maximum number of threads in the thread pool
60,
//The maximum idle time of threads in the thread pool, after which idle threads will be recycled
TimeUnit.SECONDS,
//time unit
new ArrayBlockingQueue(500),
//queue
new ThreadPoolExecutor.CallerRunsPolicy());
//rejection policy

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

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

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线