2

我刚刚开始练习使用线程池。我正在用 Java 创建一个服务器-客户端银行应用程序,我浏览了一些 Oracle 的文档,并且正在考虑使用缓存线程池。但是我进行了一些计数测试,似乎固定线程池更快。缓存的线程池滞后,似乎创建了太多不必要的线程。(或者我在这里做错了什么)。

我的问题是,在现实世界的情况下,哪个更有效?或者是否有另一种更有效的池。

另外,在我的计数测试中,我有几行:

ExecutorService executor = Executors.newCachedThreadPool();

    for (int i = 0; i < 500; i++) {
          Runnable worker = new serv(10000000L + i);
          executor.execute(worker);
    }

在上面的几行中,未使用的线程是否会自动重用(而不是创建新线程),还是我必须添加其他内容以确保发生这种情况?

4

2 回答 2

1

Executors.newCachedThreadPool() API 中有解释

六十秒内未使用的线程将被终止并从缓存中删除。因此,保持空闲足够长时间的池不会消耗任何资源。

于 2013-05-11T05:04:19.767 回答
1

我迟到了,您已经接受了另一个答案,但这是我的看法:

newCachedThreadPool()除非您知道自己在做什么,否则我不建议您使用。原因是它会创建尽可能多的线程来执行提交给它的任务。这可能会导致不良情况,例如描述符用完,甚至由于创建了太多线程而导致 JVM 崩溃。虽然,它确实会在 60 秒后从池中删除空闲线程,但它仍然会导致无限增长。

回到你的问题:

在上面的几行中,未使用的线程是否会自动重用(而不是创建新线程),还是我必须添加其他内容以确保发生这种情况?

这取决于。假设您的每个都Runnable worker需要很长时间才能完成(例如 2 分钟)。因此,您最终将在循环中创建 500 个线程。一旦所有任务完成,这 500 个线程将在内存中停留 60 秒,然后将被认领。

如果您希望重复使用线程,请使用“Executors.newFixedThreadPool(...)”并指定您希望使用的线程数。如果您提交的任务多于线程数,则任务将在队列中等待,直到有线程可用。

于 2013-05-12T04:49:57.147 回答