按参数排序的Java多线程

时间:2012-03-27 09:51:36

标签: java multithreading

网络协议解析器代码,在单个线程中解析下面的层。解析一些procotol后得到id唯一的对话框。 对于网络协议解析器项目;有一个消息解析器,解析具有多个层的消息(例如,ethernet,ip,tcp等)。解析字段之一是层中间的对话框ID;这意味着在获取之前需要进行一些解析操作。获得对话框id解析后的操作应该(因为性能)多线程。 约束是具有相同对话框ID的消息应按相同顺序处理。我有一些想法但不确定是否优雅。

  1. 创建10个队列,该队列是对话框id的最后一位,每个队列解析单独的线程。
  2. 关于对话框ID的模块化操作的多个执行程序类似于第一个选项。
  3. 如何将消息作为多线程处理?

    更多解释; 有多个消息相同的对话框ID,它应该处理相同的顺序。这些对话框ID之间没有关联,我的意思是对话框id = 100可以在对话框id = 99之前处理。

    示例消息的传入顺序

    1. Dialog id = 100
    2. Dialog id = 99
    3. Dialog id = 98
    4. Dialog id = 100
    5. Dialog id = 100
    6. Dialog id = 98
    7. Dialog id = 99
    8. 消息4应在消息1之后的消息5之前处理。消息4 - 消息2或消息4 - 消息3等之间没有任何顺序。

2 个答案:

答案 0 :(得分:0)

您需要跟踪当前正在处理的任何邮件的对话框ID,因为在上一个邮件完成之前,您无法开始处理具有相同对话框ID的其他邮件。

所以我建议如下:将数据包存储在列表列表中。主列表包含每个对话框ID的一个条目,其中至少有一条未处理的消息。内部列表包含该对话框ID当前未处理(或未完全处理)的所有消息。

收到新消息时:检查当前处理消息的表。如果有一个具有相同的对话框ID,请将此消息链接在其后面。如果没有,请使用此对话框ID在表中创建一个新条目。将其标记为已准备好处理并唤醒任何正在睡眠的线程。

处理消息:检查当前处理消息的表。如果没有标记为就绪,请等待一个标记为准备就绪。如果您发现一个已标记为就绪,请从该内部列表中获取头部消息,并将该列表标记为正在处理中。处理完毕后,如果没有链接到它的消息(使用相同的对话框ID0,请将其从主列表中删除。否则,删除我们已处理的消息并将其标记为准备处理。

答案 1 :(得分:0)

好的,鉴于你对问题的评论中的编辑和我的假设,我可能会做以下(我认为这与你的建议很接近)。请注意,我假设处理顺序很重要,但不是生成任何结果的顺序(因为您需要在每个有效负载项上使用序列ID)。

我建议如下:

  1. 使用基于队列的机制来确保执行的顺序 具有相同对话框ID的项目。这可能是并发的 队列实现或JMS队列,具体取决于分发 你的系统。
  2. 根据总有效负载确定所需的队列数。
  3. 具有相同dialogId的所有项目必须转到同一队列。多 不同的dialogIds可以转到同一个队列。
  4. 使用哈希标识dialogId应分配给哪个队列 或模数的id。这样,您的队列将始终包含 有效负载项目,以便对话框。
  5. 或者:

    (a)从每个队列中挂起多个工作线程以同时处理项目,     从队列中按顺序排列。这提供了最高的并发性(在     限制你的硬件)但你确实冒两个相同的风险     对话框ID按顺序启动但是无序完成(即1001_1启动     首先是睡觉,1001_2开始并在那段时间内完成。

    (b)从每个队列中仅挂起一个工作线程来处理该队列中的项目     严格按顺序排列一个。您现在将每个队列的线程数减少到     只有一个,但这样做,你保证了该队列的处理顺序     (以及在其上处理的所有dialogIds)。

    (c)As(b)但每个对话框id有一个线程(对于在该队列上处理的所有id)     可以向前看,只处理具有该ID的线程。这保证了     订购并提高吞吐量(即更多线程)。

    (d)As(a)有多个线程在所有id上运行但会锁定对话框id     确保处理按顺序完成。管理要做的事情需要很多开销     当对话框ID被锁定时 - 启动新队列?重新排队?

  6. 在任何情况下,您始终可以为每个队列至少拥有一个线程,并且最多可以为您的设置设置多个队列。这样就可以实现一些并发性。此外,您可以越多地在队列中传播对话框ID。其他注意事项是对队列进行负载平衡。