Executors 工具类的基本方法如下:

从上图中也可以看出,Executors的创建线程池的方法,创建出来的线程池都实现了ExecutorService接口。常用方法有以下几个:
newFiexedThreadPool(int Threads):创建固定数目线程的线程池。
newCachedThreadPool():创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
newSingleThreadExecutor()创建一个单线程化的Executor。
newScheduledThreadPool(int corePoolSize)创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
阿里巴巴Java开发手册中也明确指出,而且用的词是『不允许』使用Executors创建线程池。

为什么不允许使用:因为有些创建线程池使用了无界队列可能产生**OOM**
Java中的BlockingQueue主要有两种实现,分别是ArrayBlockingQueue 和 LinkedBlockingQueue。
**ArrayBlockingQueue**是一个用数组实现的有界阻塞队列,必须设置容量。
**LinkedBlockingQueue**是一个用链表实现的有界阻塞队列,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE。
这里的问题就出在:不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE。也就是说,如果我们不设置LinkedBlockingQueue的容量的话,其默认容量将会是Integer.MAX_VALUE。
创建线程池的正确姿势
避免使用Executors创建线程池,主要是避免使用其中的默认实现,那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池。在创建的同时,给BlockQueue指定容量就可以了。
private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(10));
本文详细解析了Java中使用Executors工具类创建线程池的潜在问题,特别是无界队列可能导致的OOM错误。介绍了正确的线程池创建方式,通过自定义ThreadPoolExecutor并设置阻塞队列容量,避免资源过度消耗。
5291

被折叠的 条评论
为什么被折叠?



