代码之家  ›  专栏  ›  技术社区  ›  Amin Heydari Alashti

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

  •  0
  • Amin Heydari Alashti  · 技术社区  · 7 年前

    在一个多线程程序中,我使用了NewFixedThreadPool,线程数为10。

    我遇到的第一个问题是系统中活动线程的数量,“ps huh p pid wc-l”记录的线程数量显示系统中活动线程的数量要大得多,即80个线程。此外,执行线程的程序从队列中读取消息,然后通过消息激发每个线程。

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

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

    根据上述问题,我的问题如下:

    • NewFixedThreadPool(n)同时拥有最多n个线程,这难道不是一个确定的规则吗?
    • 如果线程数是固定的,那么为什么会出现GC异常?
    • 最后一个问题怎么可能?

    另外,我测试了

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

    但没有改变。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Amin Heydari Alashti    7 年前

    事实上,上述问题解决了。我将描述问题的每个部分: “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方法。