Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:在时间关键型应用程序中实现高性能多线程的最佳方法是什么?_Java_Multithreading_Concurrency_Time Critical - Fatal编程技术网

Java:在时间关键型应用程序中实现高性能多线程的最佳方法是什么?

Java:在时间关键型应用程序中实现高性能多线程的最佳方法是什么?,java,multithreading,concurrency,time-critical,Java,Multithreading,Concurrency,Time Critical,我正在使用Java8开发一个网络代理应用程序。对于入口,主要逻辑是数据处理循环:在入站队列中获取数据包,处理内容数据(例如协议采用),然后将其放入发送队列。设计中允许使用多个虚拟TCP通道,因此数据处理线程(在数据处理线程列表中)在特定时间段处理一组通道,作为整个作业的一部分(例如,对于具有通道的通道。通道ID%NUM_DATA_PROCESSING_THREADS=0,由负载平衡计划程序确定)。通道存储在一个数组中,通过使用通道化的作为单元索引进行访问,该单元由一个类包装,该类提供了诸如注册、

我正在使用Java8开发一个网络代理应用程序。对于入口,主要逻辑是数据处理循环:在入站队列中获取数据包,处理内容数据(例如协议采用),然后将其放入发送队列。设计中允许使用多个虚拟TCP通道,因此数据处理线程(在数据处理线程列表中)在特定时间段处理一组通道,作为整个作业的一部分(例如,对于具有
通道的通道。通道ID%NUM_DATA_PROCESSING_THREADS=0
,由负载平衡计划程序确定)。通道存储在一个数组中,通过使用
通道化的
作为单元索引进行访问,该单元由一个类包装,该类提供了诸如
注册
取消注册
getById
大小
等方法,该实例在程序中称为
通道存储
。我需要使用这些方法在主逻辑(数据处理循环)中用不同的线程(至少调度线程、数据处理线程和控制操作线程从GUI中销毁一个通道),然后需要考虑这些线程之间的并发性。
  • 使用
    synchronized
    或围绕
    寄存器
    注销
    getById
    等的可重入锁。这是最简单且线程安全的方法。但我对锁(CAS)机制存在性能问题,因为我需要在
    通道存储上执行操作
    (尤其是
    getById
    )的频率非常高

  • 通过
    executor.execute(runnable)
    和/或
    executor.submit(可调用)将
    CHANNEL\u STORE
    的操作指定给SingleThreadExecutor
    。关注的是在数据处理循环中的每个这样的目的地创建可运行/可调用的性能:创建可运行实例并调用
    执行
    –我不知道这会比同步或可重入锁更具扩展性。实际上(到目前为止)有post操作,所以在数据处理循环中只放置RUNABLE,不需要等待可调用的返回,尽管在控制循环中需要post操作。

  • 通过一对ArrayBlockingQueue(而不是Executor)将
    通道存储
    的操作指定给一个专用任务,每次访问
    通道存储
    ,将一个任务指示符和一个参数附件放在第一个队列中,然后通过阻塞方法
    在该队列上执行专用线程循环
    并在
    CHANNEL_STORE
    上操作。然后,它将结果放入第二个队列,让指示符继续post操作(但是目前无需)。我认为这是最快的,假设JVM中的阻塞队列是无锁的。这方面的问题是代码非常混乱且容易出错

  • 我认为第二个和第三个可以称为“序列化”

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

    问题:

  • 与第一种方式相比,第二种方式的性能如何

  • 对我的情况有什么建议


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

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


    您可以在lmax Disruptor库中找到这方面的一个很好的实现。请参阅以了解更多信息。但请记住,它不是魔术,必须根据您的用例进行调整。

    感谢您的推荐。lmax Disruptor似乎适合我的场景,我相信它可能会为我节省大量的时间。但是,文档是不容易理解,在将其应用于我的程序之前,我仍在尝试了解整个过程。一旦我完成,我将接受答案。马丁·福勒(Martin Fowler)写了一篇关于破坏者的好文章,并给出了一些解释和建议()。你还可以找到关于破坏者的更实用的介绍。