由于不知线程池的 bug, 某 Java 程序员叕被祭天
池化技术常用于缓存创建性能开销较大的对象,即事先创建一些对象成为池中之物,使用时再从池中捞出,用完归还以复用。
手动声明线程池
JDK 的Executors
但是阿里有话说:
他说的弊端案例真的这么严重吗?
newFixedThreadPool 导致 OOM
初始化一个单线程的 FixedThreadPool,向线程池提交任务,每个任务都会创建个较大字符串然后休眠
执行程序后不久 OOM:
复制代码
newFixedThreadPool
其默认构造器竟然是一个Integer.MAX_VALUE
虽然使用newFixedThreadPool
可以固定工作线程数量,但任务队列几乎无界。如果任务较多且执行较慢,队列就会快速积压,内存不够就很容易导致 OOM。
newCachedThreadPool 导致 OOM
复制代码
OOM 是因为无法创建线程,newCachedThreadPool 这种线程池的最大线程数是 Integer.MAX_VALUE,基本无上限,而其工作队列 SynchronousQueue 是一个没有存储空间的阻塞队列。所以只要有请求到来,就必须找到一条工作线程处理,若当前无空闲线程就再创建一个新的。
由于我们的任务需 1 小时才能执行完成,大量任务进来后会创建大量的线程。我们知道线程是需要分配一定的内存空间作为线程栈的,比如 1MB,因此无限创建线程必然会导致 OOM:
复制代码
参考
《阿里巴巴 Java 开发手册》
评论