澄清ExecutorService

时间:2015-07-02 18:14:45

标签: java multithreading executorservice

我最近阅读了有关向ExecutorService提交任务的信息,其中任务实现了Runnable界面。如果我错了,请纠正我,但是:

  • 我的理解是您可以创建ThreadPool并专门定义此池可以包含的线程数。这样做的原因是创建一个缓存的线程池,后者可能会崩溃,如果你提供太多的任务?另外,我想知道,您希望线程池包含的线程数可以传递的最大值是多少?是什么阻止我传递一个没有意义的任意大整数,比如100000?
  • 即使使用ExecutorService,有什么好处?我理解它为你抽象了一些你的任务的实例化/处理,但我想除此之外,我在更深层次上不了解更多

这是真的吗?

3 个答案:

答案 0 :(得分:3)

回答您的第一点:

  

我的理解是你可以创建一个ThreadPool和   具体定义此池可包含的线程数。是个   这样做的原因是创建了一个缓存的线程池   如果喂它太多任务,后者会崩溃吗?

ExecutorService有很多实现,例如newCachedThreadPool()newCachedThreadPool(ThreadFactory threadFactory)newFixedThreadPool(int nThreads),其中许多实现创建一个缓存的线程池,而许多实现不像固定线程池。 固定线程池不是缓存线程池的替代品,但它们都是选项。
因此,开发人员应根据需求进行选择。如果你想完全控制线程池然后有一个固定大小的线程池,并且将保证无论有多少任务,在池中将只有那么多线程,这意味着在你的应用程序中将只是那些额外的线程。

  

另外,我想知道,你可以传递的最大值是多少   您希望线程池包含的线程数?到底是什么   阻止我传递一个没有意义的任意大整数,   说100000?

据我所知,没有强硬规则定义你可以在线程池中放置多少个线程。这实际上取决于您的JVM可以处理多少个线程。例如, 32位JVM可以处理的线程数少于64位JVM 。所以,如果你使用的是64位JVM,那么你可以更加豪华 没有什么能阻止开发人员放置一些无意义的数字,但是会导致线程占用,性能下降,内存不足甚至JVM崩溃。

回答你的第二点:

  

即使使用ExecutorService,有什么好处?一世   明白它抽象了一些实例化/处理   你的任务,但我想除此之外,我不太了解   更深层次的

真正的优势在于你编程接口。因此,您可以选择多个ExecutorService实施,例如ScheduledThreadPoolExecutorThreadPoolExecutor等。此外,如果您使用ExecutorService,还有许多其他选项可供选择

  • 在固定间隔后启动一个线程
  • 一次调用任何任务,让你的线程池执行它们

阅读ScheduledThreadPoolExecutorThreadPoolExecutor中提供的方法,您将意识到它们提供的方法的强大功能。

希望这有帮助!

<小时/> 编辑:根据@ pens-fan-69的输入
请阅读this article,了解JVM可以支持的线程数

堆栈大小

整个JVM进程由Java线程组成,有些是内部JVM线程,如主线程,GC线程,终结器线程等,而有些则是用户定义的线程。

无论是内部线程还是用户定义线程,每个线程都会分配一部分堆栈来放置运行时信息。 JVM参数 -Xss < / strong>定义堆栈大小。例如,如果堆栈大小(-Xss)是64KB,则意味着JVM中的每个线程将具有64KB来存储运行时信息。

如果堆栈大小不足,则抛出堆栈溢出异常。

因此,JVM中可存在的最大线程数取决于堆栈大小。 堆栈大小越大,线程数越少,反之亦然。

默认堆栈大小将根据操作系统而有所不同。下图: enter image description here

答案 1 :(得分:2)

  1. 存在固定线程池的原因是您可能需要限制应用程序创建的线程数(以及控制资源使用情况)。每个进程的线程数没有明确的限制,它取决于操作系统和主机(通常是内存)。
  2. 使用执行程序服务的好处是,只需将一个实现替换为另一个实现,就可以更改多线程行为。比如说,只需在Executors上调用不同的方法就可以从有限数量的线程切换到缓存的线程池,并且不需要更改代码。

答案 2 :(得分:2)

  1. 启动线程很昂贵,应尽可能避免。线程池缓存线程,以便它不那么频繁地执行此操作。

  2. 线程是一种有限的资源,您可以用完它,因此最好限制启动的最大数量。如果队列中的项目处理速度不够快,您可以增加数量,但是您可以以受控方式执行此操作,这样您就不会因为达到最大值而导致JVM崩溃。支持的最大值将由您使用的操作系统配置和硬件决定。

  3. 我喜欢为整个应用程序创建单个线程池,然后将其用于所有类型的后台工作。在Web应用程序中,您必须确保在应用程序停止时结束线程。拥有单个线程池使这很容易。否则,您将不断遇到线程泄漏,因为您忘记停止线程。

  4. 是的,我知道不建议在Web应用程序中启动线程。只要你结束它,它对我来说就可以了。