8

我正处于一个问题之中,我无法决定采用哪种解决方案。

这个问题有点独特。这么说吧,我不断地从网络接收数据(每秒 2 到 4 次)。现在每个数据都属于一个不同的,比如说,组。现在,让我们将这些组称为 group1、group2 等。

每个组都有一个专用的作业队列,来自网络的数据被过滤并添加到相应的组中进行处理。

起初,我为每个组创建了一个专用线程,该线程将从作业队列中获取数据,对其进行处理,然后进入阻塞状态(使用链接阻塞队列)。

但是我的学长建议我应该使用线程池,因为这样线程不会被阻塞,并且可以被其他组用于处理。

但事情是这样的,我获取的数据足够快,线程处理它所花费的时间足够长,线程可能不会进入阻塞模式。这也将保证数据按顺序处理(作业 1 在作业 2 之前完成),在池中,这种情况很少发生,可能不会发生。

我的学长也坚持这样一个事实,即池化也会为我们节省大量内存,因为线程是 POOLED 的(我认为他真的很喜欢这个词;))。虽然我不同意这一点,因为我个人认为,是否每个线程都获得了自己的堆栈内存。除非线程池中有我不知道的东西。

最后一件事,我一直认为汇集有助于短期内大量出现工作。这是有道理的,因为线程生成会导致性能下降,因为初始化线程所花费的时间远远超过完成工作所花费的时间。因此,池化在这里有很大帮助。

但在我的情况下,group1、group2、...、groupN 始终保持活动状态。因此,无论是否有数据,它们仍然会存在。所以线程生成不是这里的问题。

我的上级不相信,并希望我使用池解决方案,因为它的内存占用很大。

那么,该走哪条路呢?

谢谢你。

4

2 回答 2

4

创建线程会消耗资源,包括每个线程的默认堆栈(IIR 512Kb,但可配置)。因此,池化的优势在于您会受到有限的资源影响。当然,您需要根据您必须执行的工作来调整池的大小。

对于您的特定问题,我认为关键是在每种情况下实际测量性能/线程使用情况等。除非您遇到限制,否则我可能不会担心任何一种方式,除了确保您可以将一种实现换成另一种而不会对您的应用程序产生重大影响。请记住,过早的优化是万恶之源请注意

“过早优化”是一个短语,用于描述程序员让性能考虑影响一段代码的设计的情况。这可能会导致设计不如预期的干净或代码不正确,因为代码因优化而变得复杂,而程序员因优化而分心。

于 2012-07-28T11:57:49.227 回答
4

好问题。正如您所说,池化确实可以节省您的初始化时间。但它还有另一个方面:资源管理。我在这里问你这个——你有多少组(阅读专用线程)?它们是否在应用程序的执行期间动态增长?

例如,考虑这个问题的答案是肯定的情况。新的组类型是动态添加的。在这种情况下,您可能不想为每个线程专门分配一个线程,因为从技术上讲,对将创建的组的数量没有限制,您将创建大量线程并且系统将进行上下文切换而不是实际工作. 到救援线程池的线程池允许您指定对可能创建的最大线程数的限制,而不考虑负载。因此,应用程序可能会拒绝某些请求的服务,但通过的请求会得到妥善处理,而不会严重耗尽系统资源。

考虑到上述情况,我很有可能在您的情况下,为每个组设置一个专用线程是非常好的!

你的前辈相信它会节省内存也是如此。确实,一个线程占用了堆上的内存,但它真的有这么多吗,如果它是一个预定义的数量,比如 5。即使是 10-也可能没问题。无论如何,除非您是先验的并且绝对确信您确实有问题,否则您不应该使用池化!

池化是一种设计决策,而不是架构决策。您可以在开始时不进行池化并继续进行优化,以防在遇到性能问题后发现池化是有益的。

考虑到请求的序列化(按顺序执行),无论您使用的是线程池还是专用线程。顺序执行是队列与单个处理程序线程相结合的属性。

于 2012-07-28T12:11:57.180 回答