使用newFixedThreadPool会导致一些奇怪的问题

时间:2019-01-23 08:15:32

标签: java multithreading

在多线程程序中,我使用了带有10个线程号的newFixedThreadPool。

我遇到的第一个问题是“ ps huH p PID | wc -l”记录的系统上活动线程的数量显示系统中活动线程的数量要多得多,为80线程。另外,执行线程的程序从队列中读取消息,然后由该消息激发每个线程。

第二个问题是Java堆空间异常。实际上,它是在程序执行一段时间后发生的。

最后,最后一个问题是,虽然线程无法甚至无法从队列中读取消息,但是线程的输出表明它们是活动的并且正在处理某些数据。

根据上述问题,我的问题列在下面:

  • 难道不是newFixedThreadPool(n)同时具有最多n个线程的规则吗?
  • 如果线程数固定,那么为什么GC异常到达?
  • 最后一个问题怎么可能?

我也测试了

new ThreadPoolExecutor((10, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2 * 10));

但没有任何变化。

1 个答案:

答案 0 :(得分:0)

事实上,上述问题得以解决。我将描述问题的每个部分: “ ps huH p PID | wc -l”:该命令无法获取使用ThreadPool仍在运行的实际线程数,而是显示作业的OS级线程总数。

newFixedThreadPool(n):具有一个无限制的阻塞队列,这意味着,当您的程序输入可用时,它将创建一个对象并将其添加到该阻塞队列中。结果,当存在大量输入元素时,可能会出现内存问题。

最后,以下选项不起作用,因为ArrayBlockingQueue的默认实现具有一个offer方法,该方法用于向其中插入新对象。

new ThreadPoolExecutor((10, 10, 10, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2 * 10));

顾名思义,offer方法尝试将请求的对象添加到arrayBlockingQueue的末尾。否则,如果使用ArrayBlockingQueue的put方法,则将解决该问题。为此,我扩展了ArrayBlockingQueue并通过在offer的方法阻塞队列中调用其put方法来覆盖它的offer方法。