向仅含2线程的ExecutorService无限提交任务会有何影响?
关于FixedThreadPool无限提交任务的问题解答
1. 阻塞队列满时是否会阻止添加任务?
首先明确:Executors.newFixedThreadPool(2) 默认使用无界的LinkedBlockingQueue(容量为Integer.MAX_VALUE),这种情况下队列永远不会被填满,调用submit()提交任务时不会被阻塞,也不会触发拒绝策略。
如果是自定义了有界阻塞队列的线程池(比如手动创建ThreadPoolExecutor并指定有界队列),当队列满且核心线程数已达上限时,会触发线程池的拒绝策略:
- 默认策略是
AbortPolicy,直接抛出RejectedExecutionException,阻止任务添加; - 若使用
CallerRunsPolicy等其他策略,会由提交任务的线程执行该任务,不会阻止添加但会占用调用线程资源。
2. 是否会占用大量内存?
会。无界队列会持续堆积未执行的任务,每个Callable任务对象(包括其持有的上下文数据)都会占用堆内存。随着任务不断提交,内存占用会持续攀升,直到JVM堆内存耗尽,触发OutOfMemoryError,导致应用崩溃。
3. 主要副作用与影响
- 内存耗尽与应用崩溃:最直接的后果是堆内存被堆满,抛出OOM,整个进程终止。
- 任务响应延迟剧增:堆积的任务需要等待前面的任务执行完成才能被处理,任务执行等待时间会越来越长,业务响应性能严重下降。
- 资源泄漏风险:如果任务持有外部资源(如数据库连接、文件句柄、网络连接),堆积的任务会长期占用这些资源,导致资源耗尽,其他依赖该资源的业务无法正常运行。
- CPU/IO资源异常:如果任务是CPU密集型,线程池的2个核心线程会持续满负荷运行,CPU使用率长期居高不下;如果是IO密集型,线程会频繁处于等待状态,但堆积的任务依然会占用大量内存。
- 调试定位困难:任务堆积到一定程度后,排查问题时很难快速定位到具体是哪些任务导致的内存占用,增加故障排查成本。
内容的提问来源于stack exchange,提问作者90abyss
相关产品推荐
相关产品推荐

