1

任何人都可以用例子解释我们为什么要使用线程池。

从理论上讲,我知道线程池与 Executors 的使用。

我已经阅读了许多教程,但是我没有得到任何关于我们为什么要使用线程池的实际示例,它可以是 newFixedThreadPool 或 newCachedThreadPool 或 newSingleThreadExecutor

在可扩展性和性能方面。

如果有人向我解释有关性能和可扩展性的示例吗?

4

4 回答 4

2

首先,查看我昨天写的关于线程池的描述:Android Thread Pool to manage multiple bluetooth handlering threads?(好吧,它是关于 android 的,但对于经典 java 来说也是一样的)。

我似乎总是发现使用线程池的主要用途是它很好地解决了一个非常常见的问题:生产者-消费者。在这种模式中,有人需要不断地发送工作项(生产者)以供其他人(消费者)处理。工作项是从一些类似流的源中获取的,例如套接字、数据库或磁盘文件的集合,并且需要多个工作人员才能有效地处理。此处可识别的主要组件是:

  • 生产者:不断发布工作的线程
  • 发布作业的队列
  • 消费者:从队列中获取作业并执行它们的工作线程

除此之外,还需要使用同步来使所有这些工作正常,因为在没有同步的情况下读取和写入队列会导致数据损坏和不一致。此外,我们需要使系统高效,因为消费者不应该在无事可做时浪费 CPU 周期。

现在这种模式很常见,但是从头开始实现它需要相当大的努力,而且容易出错,需要仔细审查。

解决方案是线程池。它非常方便地管理工作队列、消费者线程和所有需要的同步。您需要做的就是扮演生产者的角色并为池提供任务!

于 2012-03-15T10:56:03.953 回答
1

我会从一个问题开始,然后才尝试为它找到解决方案。

如果您以自己的方式开始,您可能会找到一个解决方案来寻找要解决的问题,并且您可能会不恰当地使用它。

如果您想不出线程池的用途,请不要使用它们。;)

人们犯的一个常见错误是假设因为他们现在有很多 cpu,所以他们必须使用它们,就好像这本身就是一个原因一样。这就像说我有很多磁盘空间,我必须找到一种方法来使用它们。

使用线程池的一个很好的理由是提高 CPU 绑定进程的性能和 IO 绑定进程的简单性(而不是使用一个线程的非阻塞 IO)

如果您有一个繁忙的 CPU 密集型进程来执行可以独立执行的任务,那么您就有一个很好的线程池用例。

注意:线程池通常只有一个线程。这些有特定的静态工厂。如果您想要一个简单的后台工作人员,这可能是一个选择。

注意 2:一个常见的错误是假设 CPU 密集型任务将在数百或数千个线程上运行得最好。最佳线程数可以是您拥有的核心数或 CPU 数。一旦所有这些都忙起来,您可能会发现额外的线程只会增加开销。

于 2012-03-15T10:33:12.913 回答
1

初始化一个新线程(和它自己的堆栈)是一项代价高昂的操作。

线程池用于通过重用已创建的线程来避免这种成本。因此,使用线程池可以获得更好的性能,然后每次都创建新线程。

另请注意,创建的线程在使用后可能需要“删除”,这会增加垃圾收集的成本和它发生的频率(因为内存填得更快)。

这种分析只是从性能的角度来看。目前我想不出在可扩展性方面使用线程池的优势。

于 2012-03-15T10:43:15.540 回答
-1

我用谷歌搜索“为什么使用 java 线程池”并发现:

线程池为线程生命周期开销问题和资源抖动问题提供了解决方案。

http://www.ibm.com/developerworks/library/j-jtp0730/index.html

newCachedThreadPool 方法创建一个带有可扩展线程池的执行器。此执行器适用于启动许多短期任务的应用程序。newSingleThreadExecutor 方法创建一个执行器,一次执行一个任务。

http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html

于 2012-03-15T10:39:00.940 回答