2010-07-28 216 views
0

我现在正在为服务器客户端应用程序工作(仅用于学习目的),并且正在尝试获取有关此应用程序中有关线程的设计决策的信息。多线程vs单线程

目前我有一个线程负责与客户端的所有非阻塞io。当它接收到任何数据时,它将它发送给一个工作线程,该线程从这些字节中创建一个“指令集”,然后相应地对其执行操作。但是,根据指令集,它可以对任意数量的数百个对象起作用(每个对象将在2到12个可以与之交互的客户端之间加盖)。我想知道是否应该处理同一个线程上的所有指令集,并且在处理每个集合时阻塞,或者如果我应该为每个对象创建单独的线程,然后将每个接收到的指令集传递给给定的对象线程处理。

我的问题归结为什么时候(如果有的话)有更多不活动的线程正在等待数据减慢系统,相比之下,有一个工作线程处理所有数据(以及处理每条指令时的块组)。

如果我为每个对象创建了一个单独的线程,那么我认为它可以增加并发性,因为一旦主工作线程创建了一个指令集,它就可以传递它来处理,并且无意地开始处理下一个指令系统。

但是,我一直听说如何创建和管理线程有一个底层成本,因为操作系统必须管理它们。因此,如果我为最多可以有2个客户端进行交互的对象创建一个线程,管理它的底层成本会否定它的并发利益,只有2个客户端可以利用该并发?

与往常一样,任何意见/文章不胜感激:)

回答

3

我建议通过以下的Java EE应用服务器树立了榜样。

为传入请求和处理程序线程的池设有队列。当请求进入时,让控制器从池中取出一个处理程序线程,将请求从队列中取出,并将其交给处理程序线程处理。线程完成后,将其放回池中。

如果请求数量大于处理程序线程的数量,则队列允许它们累积并等待线程变为可用。

这样的设计给你带来两个好处:

  1. 它可以让你设定的处理线程池的大小和它匹配到你的服务器资源
  2. 当他们超过池容量,因此会扼杀传入的请求你没有阻止和等待或失去请求。

并发是你的朋友在这里。这将有助于保持服务器的可扩展性。

+0

这是一个更优雅的解决方案,然后我就是想象。谢谢:) – vimalloc 2010-07-28 00:31:33

0

如果线程实际上处于睡眠状态,则开销成本应该不过是首先启动它们而花费的成本。沉睡的线程有一个相当有效的方法,直到需要时才能入睡:等待中断。 (注意一种常见的睡眠方法是在时钟中断后唤醒,这就是你如何指定应该睡眠的时间)。如果那些线程没有利用硬件,因为它们正在唤醒某些类似定时器的东西,而不是某个更特定于您的程序的东西,那么开销可能是天文数字,因为处理器将强制执行所有上下文开关特别是清空缓存。

+0

虽然睡眠线程的CPU成本不算什么,但内存开销可能相当高,如果有大量睡眠线程持续存储大块数据,则效果与内存大致相同泄漏。 – 2010-07-28 01:09:28

0

单向测试。有时你必须阻止,除非你确信自己的计算能力,否则你不能只是冲击一切。机器越慢/功能越差,阻塞越多,就会变得无用。设计你的应用程序以适应这种情况。更好的是让它跟踪正在发生的事情并让它自行调整。