前言
JUC里的线程池,使用
Executors.newFixedThreadPool
可以创建线程数的线程池,细看其源码,其实它调用的是核心线程数和最大线程数相等的线程池,并且使用的工作队列类型是 LinkedBlockingQueue(无边界),也就是说负载及其大的情况下,队列中的任务可以无限堆积,那么就很容易会造成OOM。下面模拟一下这种情况造成的OOM
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
代码案例
演示中创建一个只有一个线程的 固定线程池,然后用该线程池去处理 int最大值个任务,每个任务执行很长时间不退出,这样任务队列里就会积满很多处理不完的任务。为了方便先设置JVM的内存参数调小 -Xmx10m -Xms10m,启动时就会很快报OOM了
/**
* 演示 固定大小的线程池报OOM错
*
* @author: lvzb31988
* @date: 2023/01/10 18:05
*/
public class FixThreadPoolOOMTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(1);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
pool.execute(new Task());
}
}
public static class Task implements Runnable {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "正在处理业务.....");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
启动后直接OOM