Executors创建线程池隐藏的坑

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/oyc619491800/article/details/96481587

这篇文章主要针对对线程池有一定了解的人,不了解原理的人建议先学习一下线程池的原理。
一般的,我们可能习惯这样创建线程池:

		ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorService executorService1 = Executors.newSingleThreadExecutor();
        ExecutorService executorService2 = Executors.newFixedThreadPool(3);

看起来并没什么毛病。。。下面我们看看这几个方法实现的源码,你会发现其实都是通过ThreadPoolExecutor来创建的,这个ThreadPoolExecutor有多个构造函数,其中参数最多的为:
在这里插入图片描述
其他构造函数最终都是调了这个。然后我们先从newCachedThreadPool的实现看起,上源码:
在这里插入图片描述
你会发现这个最大线程数设置的是Integer.MAX_VALUE,相信看到这里大家应该意识到可能会发生什么问题了,没错,如果创建了大量的线程就有可能引发OOM。newScheduledThreadPool的分析过程和引发问题与此一致。
接下来我们再看看newSingleThreadExecutor的实现:
在这里插入图片描述
这里我们还看不出什么问题,我们再接着看new LinkedBlockingQueue(),
在这里插入图片描述
没错,你又看到了Integer.MAX_VALUE,这就是工作队列的大小,如果堆积了大量的任务,同样可能引发OOM。newFixedThreadPool的分析过程和
newSingleThreadExecutor一样,问题也一样,我就不再赘述。

既然有可能存在这样的坑,那么我们怎么避免呢?
我们可以这样创建:

		ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("francis-test").build();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10, 5, TimeUnit.SECONDS, 
        								new LinkedBlockingDeque<>(100), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

根据实际场景设置各参数,这样一来踩坑的几率会更小。

猜你喜欢

转载自blog.csdn.net/oyc619491800/article/details/96481587