Java 并行化任务,但在输出中保持输入顺序
我有一个子系统,看起来像这样:Java 并行化任务,但在输出中保持输入顺序,java,parallel-processing,threadpool,Java,Parallel Processing,Threadpool,我有一个子系统,看起来像这样: [read] [decode] [deliver] Byte --> Undecoded --> Decoded --> Output queue stream message message 输入是套接字/字节流。第一步是阅读信息。下一步是解码消息(并将结果存储在消息对象中)。最后一步是传递信息 我想并行解码步骤,但我必须保持输
[read] [decode] [deliver]
Byte --> Undecoded --> Decoded --> Output queue
stream message message
输入是套接字/字节流。第一步是阅读信息。下一步是解码消息(并将结果存储在消息对象中)。最后一步是传递信息
我想并行解码步骤,但我必须保持输出顺序与输入顺序相同。因此,如果接收到消息A和消息B,并且消息B的解码速度更快,我必须等到消息A发送完毕
我用Java做了一个简单的初始实现,但我的评测表明我在切换步骤中损失了太多(从“流读取器”到“解码器”,从“解码器”到输出)。在24核计算机(包括超线程)上运行测试程序时,我得到:
- 运行单线程实现时为1100 K msg/s李>
- 当运行一个简单的12线程实现时(具有大量 队列)
在执行此类问题时,是否有人可以使用模式/框架,其中工作是连续的(基于流),可以并行化,但必须根据输出进行排序?我在编写的程序(用C#)中处理这一问题的方法是在输出上有一个优先级队列。每个记录都有一个相关联的记录编号,读取时会分配该编号。这些数字从0开始增加。当一个线程处理完一条记录后,它会将该记录添加到优先级队列中 单独的输出线程的预期记录编号从零开始。此线程监视队列,等待添加预期的记录号。添加预期记录后,线程将其从队列中移除,输出它,增加其预期记录编号,然后重试
这在我的应用程序中非常有效,有四个线程处理记录,一个线程处理输出。在我编写的程序(用C#)中处理这一问题的方法是在输出上有一个优先级队列。每个记录都有一个相关联的记录编号,读取时会分配该编号。这些数字从0开始增加。当一个线程处理完一条记录后,它会将该记录添加到优先级队列中 单独的输出线程的预期记录编号从零开始。此线程监视队列,等待添加预期的记录号。添加预期记录后,线程将其从队列中移除,输出它,增加其预期记录编号,然后重试
这在我的应用程序中非常有效,有四个线程处理记录,一个线程处理输出。1100 K msg/s非常快(对于一条消息来说不到1微秒)。此时间与从队列中放入/获取消息的时间(0.1…1微秒)相当。因此,为了利用并行化,您必须将不间断处理的时间保持在1微秒(比如1毫秒)以上。如果将小消息组合成大消息,则可以完成此操作。在一个数据包中累积1000条消息,并将该数据包作为一个工作单元进行处理。并行处理单元。1100 K msg/s的速度非常快(对于一条消息来说不到1微秒)。此时间与从队列中放入/获取消息的时间(0.1…1微秒)相当。因此,为了利用并行化,您必须将不间断处理的时间保持在1微秒(比如1毫秒)以上。如果将小消息组合成大消息,则可以完成此操作。在一个数据包中累积1000条消息,并将该数据包作为一个工作单元进行处理。并行处理单元。我看到您手动创建线程。您是否考虑过使用ThreadPoolExecutor类?我看到您手动创建线程。您是否考虑过使用ThreadPoolExecutor类?