Java-用于非阻塞套接字的多线程中的多个选择器

Java-用于非阻塞套接字的多线程中的多个选择器,java,multithreading,css-selectors,nio,Java,Multithreading,Css Selectors,Nio,我正在编写一个Java应用程序,它将实例化一个类的对象,以表示已连接并注册到应用程序另一端的外部系统的客户端 每个客户机对象中都有两个嵌套类,分别表示前端和后端。前端类将持续接收来自实际客户端的数据,并向后端类发送指示和数据,后端类将从前端获取该数据,并使用系统要求的适当格式和协议将其发送到外部系统 在设计中,我们希望客户机对象的每个实例化都是一个线程。然后,在每个线程中自然会有两个套接字[EDIT],每个套接字都有自己的NIO通道[EDIT],一个客户端,一个系统端分别位于前端和后端。但是,现

我正在编写一个Java应用程序,它将实例化一个类的对象,以表示已连接并注册到应用程序另一端的外部系统的客户端

每个客户机对象中都有两个嵌套类,分别表示前端和后端。前端类将持续接收来自实际客户端的数据,并向后端类发送指示和数据,后端类将从前端获取该数据,并使用系统要求的适当格式和协议将其发送到外部系统

在设计中,我们希望客户机对象的每个实例化都是一个线程。然后,在每个线程中自然会有两个套接字[EDIT],每个套接字都有自己的NIO通道[EDIT],一个客户端,一个系统端分别位于前端和后端。但是,现在需要非阻塞套接字。我一直在阅读教程,该教程解释了如何在主线程中安全地使用选择器来处理具有连接的所有线程


但是,我需要的是多个选择器——每个选择器在各自的线程中运行。通过阅读上述教程,我了解到选择器中的键集不是线程安全的。这是否意味着,如果我尝试为每个选择器提供自己的一对套接字和通道,那么在它们自己的代表线程中实例化的单独选择器可能会创建冲突的键?将选择器向上移动到主线程的可能性很小,但根据我所给出的软件需求,这还远远不够理想。感谢您的帮助。

如果必须使用此单套接字连接,则必须将接收和写入通道中的数据的过程与数据处理本身分开。您不必委派频道。这个频道就像一辆公共汽车。总线(管理通道的单线程)必须读取数据并将其写入(线程安全的)输入队列,包括所需的信息,以便您的客户端线程可以从队列中提取正确的数据报包。如果客户机线程喜欢写入数据,则该数据将写入输出队列,然后由通道线程读取该队列以将数据写入通道


因此,从使用此连接的参与者之间共享连接的概念及其不可预测的处理时间(这是块的主要原因)转移到异步数据读取、数据处理和数据写入的概念。因此,不可预测的不再是处理时间,而是读取或写入数据的时间。非阻塞意味着,数据流尽可能恒定,不管处理该数据需要多少时间。

使用多个选择器可以,只要您不向两个选择器实例注册具有相同兴趣的相同通道(OP_读取/OP_写入等)。在多个选择器实例中注册同一通道可能会导致问题,selector1.select()可能会使用selector2.select()可能感兴趣的事件

大多数平台上的默认选择器都是基于poll()[或epoll()]的

Selector.select在内部调用
int poll(ListPointer,Nfdsmsgs,Timeout)方法。

        where the ListPointer structure can then be initialized as follows:

    list.fds[0].fd = file_descriptorA;
    list.fds[0].events = requested_events;
    list.msgs[0].msgid = message_id;
    list.msgs[0].events = requested_events;
也就是说,我建议使用ROX RPC nio教程中提到的单个选择线程。NIO实现依赖于平台,在一个平台上工作的很可能在另一个平台上不工作。我也看到了小版本的问题。
例如,AIXJDK1.6SR2使用了一个基于poll()的选择器-PollSelectorImpl和相应的选择器提供程序作为PollSelectorProvider,我们的服务器运行良好。当我转到AIXJDK1.6SR5时,它使用了基于pollset接口的优化选择器(PollSetSelectorImpl),我们在select()和socketchannel.close()中遇到了频繁的服务器挂起。我看到的一个原因是,我们在应用程序中打开了多个选择器(与理想的一个选择器线程模型相反),并且实现了如上所述的PollSetSelectorImpl。

恐怕我“我对你的回答有点困惑。你是说一个通道本身就是一个线程,一个通道是它自己的线程,还是说我应该在一个独立于客户端的线程中设置和轮询通道?在我最初的文章中,我可能不太清楚,每个客户机对象都有两个套接字和两个通道,用于在应用程序的任一侧进行通信。最初我学会了用C写套接字,我很熟悉非阻塞和非阻塞的概念,特别选择非阻塞是因为对多路通信的要求。这很危险,所以请不要投反对票。。。系统问题淹没了讨论-参见:哪个给出了更好的答案。通道并非设计为线程化thingamabob:它设计为在希望获得良好io和线程性能的编程环境中运行。整个问题被实时JSR中描述的问题深深地笼罩着。。。上面的链接提供了一个关于这件事的讨论,由了解这件事的工程师进行。我做了一些早期测试,它不是它看起来。