我刚开始练习使用线程池。我正在用Java创建一个服务器 - 客户端银行应用程序,我浏览了一些Oracle的文档,我正在考虑使用缓存的线程池。但我运行了一些计数测试,似乎固定的线程池更快。缓存的线程池滞后,似乎创建了太多不必要的线程。 (或者我在这里做错了。)
我的问题是,在现实世界中,哪种情况会更有效率?或者是否有其他类型的池更有效率。
另外,在我的计票测试中,我有几行:
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 500; i++) {
Runnable worker = new serv(10000000L + i);
executor.execute(worker);
}
在上面的行中,未使用的线程是自动重用的(而不是创建新的线程),还是还有其他东西我必须添加以确保发生这种情况?
答案 0 :(得分:1)
Executors.newCachedThreadPool()API
中有一个解释终止未使用60秒的线程并从缓存中删除。因此,长时间闲置的池不会消耗任何资源。
答案 1 :(得分:1)
我迟到了,你已经接受了另一个答案,但这是我的看法:
除非你知道自己在做什么,否则我不建议使用newCachedThreadPool()
。原因是它将创建执行提交给它的任务所需的尽可能多的线程。这可能会导致不合需要的情况,例如耗尽描述符甚至崩溃JVM,因为创建了太多线程。虽然它确实在60秒后从池中删除了空闲线程,但它仍然会导致无限制的增长。
回到你的问题:
在上面的行中,未使用的线程是自动重用的(而不是创建新的线程),还是还有其他东西我必须添加以确保发生这种情况?
这取决于。假设您的每个Runnable worker
需要很长时间才能完成(例如2分钟)。因此,您最终将在循环中创建500个线程。完成所有任务后,这500个线程将在内存中停留60秒,然后将被声明。
如果您想重新使用Threads,请使用'Executors.newFixedThreadPool(...)`并指定您想要使用的Threads数。如果您提交的任务多于线程,则任务将在队列中等待,直到线程可用。