1

我正在使用ForkJoinPool.commonPool().execute(runnable)一种方便的方式在我的应用程序的许多地方生成线程。但是在特定的调用中,调用线程中的可运行代码需要更多时间(超过 10 秒)。这可能是什么原因?如何避免这种情况?

编辑:根据@ben 的回答,避免线程池中长时间运行的进程似乎是解决方案。手动创建新线程解决了我的问题,而不是使用常见的 ForkJoinPool。

4

1 回答 1

2

因此,经过一些快速测试后,我发现了问题。看下面的示例代码:

List<Runnable> runnables = new ArrayList<Runnable>();
for (int i = 0; i < 20; ++i)
{
    runnables.add(() -> {
        System.out.println("Runnable start");
        try
        {
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {

        }
        System.out.println("Runnable end");
    });
}

for (Runnable run : runnables)
{
    //ForkJoinPool.commonPool().execute(run);
    //new Thread(run).start();
}

在两行之一中进行注释。我们创建了许多发送消息的可运行程序,闲置 10 秒,然后再次发送消息。非常简单。

当为所有 Runnables 发送Runnable start10s pass 中的每一个使用 Threads 时,所有 runnables 都发送Runnable end.

当使用 commonPool() 时,它们中的一些发送Runnable start10s 通行证,它们发送Runnable end,另一批发送,Runnable start直到它们全部完成。

这仅仅是因为系统上的内核数量决定了线程池将容纳多少线程。当所有这些都被填满时,直到一个线程被释放后才会执行新任务。

这个故事的寓意是:只有当你知道它在内部工作的方式并且这就是你想要它做的事情时才使用线程池。

于 2018-02-23T09:07:44.670 回答