多线程与单线程

时间:2010-07-28 00:19:44

标签: java concurrency

我正在研究服务器客户端应用程序(仅用于学习目的),并且我正在尝试获取信息以在此应用程序中做出有关线程的设计决策。

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

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

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

但是,我一直听说如何创建和管理线程有一个潜在的成本,因为操作系统必须管理它们。因此,如果我为一个最多可能有2个客户端能够与之交互的对象创建了一个线程,那么管理它的基础成本是否会抵消它的并发优势,只有2个客户端可以利用该并发性?

一如既往,非常感谢任何建议/文章:)

3 个答案:

答案 0 :(得分:3)

我建议遵循Java EE应用服务器设置的示例。

为传入请求创建队列,为处理程序线程创建池。当请求进入时,让控制器从池中获取处理程序线程,将请求从队列中取出,并将其提供给处理程序线程进行处理。线程完成后,将其放回池中。

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

这种设计有两个好处:

  1. 它允许您设置处理程序线程池的大小并将其与服务器资源匹配
  2. 当超过池容量时,它会限制传入的请求,因此您不会阻止并等待或丢失请求。
  3. 并发是你的朋友。它有助于保持服务器的可扩展性。

答案 1 :(得分:0)

如果线程实际上处于休眠状态,那么开销成本应该只是首先启动它们的成本。睡眠线程有一种相当有效的方法,可以在需要之前保持睡眠状态:等待中断。 (注意一个常见的睡眠方法是在从时钟中断后唤醒,这是你可以指定它应该睡眠的时间量)。如果这些线程没有利用硬件,因为它们是从计时器而不是程序更具体的东西中唤醒的,那么处理器将被迫制造的所有上下文切换的开销可能是天文数字,大多数特别是清空缓存。

答案 2 :(得分:0)

单向测试。你必须有时阻止,除非你确定你的计算能力,否则你不能只是通过一切。机器越慢/越少,越多的阻塞就越大。根据具体情况设计您的应用程序。更好的是让它跟踪正在发生的事情并让它自行调整。