首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:在时间紧迫的应用程序中,高性能多线程的最佳方法是什么?

Java:在时间紧迫的应用程序中,高性能多线程的最佳方法是什么?
EN

Stack Overflow用户
提问于 2020-10-17 17:43:02
回答 1查看 445关注 0票数 1

我正在使用Java 8开发一个网络代理应用程序。对于入口,主要的逻辑是数据处理-循环:在入站队列中获取一个数据包,处理内容数据(例如协议采用),并将其放入发送队列中。在设计中允许多个虚拟TCP通道,因此数据处理线程在数据处理线程列表中作为整个工作的一部分在特定时间内处理一组通道(例如,对于具有channel.channelId%NUM_DATA_PROCESSING_THREADS = 0的通道,该通道由负载平衡调度程序决定)。通道存储在一个数组中,并使用channeled作为单元格的索引进行访问,该索引由一个类包装,该类提供registerderegistergetByIdsize等方法,该实例在程序中称为CHANNEL_STORE。我需要在主逻辑(数据处理-循环)中使用这些方法,由不同的线程(至少是dispatcher线程、数据处理线程和控制操作线程来破坏GUI中的通道)。然后我需要考虑这些线程之间的并发性。我有几个候选方案:

  1. 使用synchronized或围绕registerderegistergetById等的重入锁。这是最简单的,也是线程安全的。但是,由于我需要在CHANNEL_STORE (特别是getById)上以非常高的频率执行操作,所以我对锁(CAS)机制有性能上的顾虑。

  1. 通过executor.execute(runnable)和/或executor.submit(callable)CHANNEL_STORE的操作指定为SingleThreadExecutor。关注的是在数据处理-循环中的每个这样的目标上创建可运行/可调用的性能:创建可运行实例并调用execute --我不知道这是否比同步或重入锁更具有扩展性。在现实中(到目前为止),虽然在控制循环中需要后置操作,但只需将可运行的操作放置在数据处理循环中,而不需要等待可调用的返回。

  1. CHANNEL_STORE的操作通过一对ArrayBlockingQueue指定给一个专用任务,而不是为每次访问CHANNEL_STORE指定执行器,将任务指示符连同参数附加到第一个队列,然后通过阻塞方法take在该队列上执行专用线程,并在CHANNEL_STORE上运行。然后,它将结果放到第二个队列中,以便设计器继续后操作(但是,目前不需要)。假设JVM中的阻塞队列是无锁的,我认为这是最快的。对此的关注是代码非常混乱,而且error-prone.

我认为第二和第三可能被称为“序列化”。

我不能简单地将任务分配给线程池进行数据处理并忘记它们的原因是,每个通道的TCP流数据包不能被乱序,它必须在每个通道库中进行串行排序。

问题:

  1. ,与第一种方式相比,第二种方式的性能如何?

  1. 对我的处境有什么建议?

我目前使用的流IO局域网读/写。如果使用NIO,NIO线程和数据处理线程之间的协调可能会带来额外的复杂性(例如post操作)。因此,我认为这个问题对于像我这样的时间关键(基于流的多通道网络)应用程序是有意义的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-17 22:27:28

如果我完全理解您的用例,这是并发编程中常见的问题。一种解决方案是使用环形缓冲区方法,它通常为同步和太多对象创建问题提供一个很好的解决方案。

您可以在lmax dispruptor库中找到一个很好的实现。有关此问题的更多信息,请参见https://lmax-exchange.github.io/disruptor/。但请记住,它不是魔术,必须适应您的用例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64405476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档