在Java NIO Reactor Pattern中的不同线程中调度事件处理程序

问题描述 投票:0回答:1

我正在使用Reactor Pattern用java NIO编写一个简单的Server应用程序。根据我的理解,Reactor类负责收集Events(例如:OP_ACCEPT,OP_READ,OP_WRITE)。

相对EventHandler将负责具体任务。因此处理程序应该能够异步运行在单独的线程中。

这是代码:enter image description here

当我运行它时,它显示一些问题,while循环继续运行,并且Selector保持返回readyOps设置为(1,4,16)。我想这是因为AcceptHanndler没有以阻挡的方式处理OP_ACCEPT。因此,即使从迭代器中删除密钥,在select()调用之后,它也会再次出现。

我不能在单独的线程中将eventHander作为runnable运行吗?

我想到了edge-triggeredlevel-triggered模型的概念。原因是因为选择器在level-triggered模型中运行?

java selector nio reactor
1个回答
2
投票

是的,选择器是电平触发的。您的案例中的标准工作流将遵循:在您检测到该通道可接受之后,从Selector中取消该键,并且仅在将该键传递给事件处理程序线程之后。事件处理程序线程将完成接受并且1)再次为OP_ACCEPT注册服务器套接字; 2)根据您要实现的协议,为OP_READ和/或OP_WRITE注册接受的客户端套接字。或者,您可以在主线程中完成接受(出于性能原因,如果有一大堆连接客户端)。

实际上,按操作类型区分线程是不可扩展的,并且由于数据局部性差,可能在SMP系统中性能较差。最好将每个客户端套接字锁定到单个线程。高性能Java服务器通常通过使一个线程专门用于接受(仅在那里注册单个ServerSocket)和N个工作线程来实现客户端套接字来实现。接受线程在循环中工作:

  1. select()中的块,直到新客户端到达
  2. 完成接受
  3. 选择最少加载的工作线程并在那里转移新接受的客户端套接字的所有权

每个工作线程都有自己的Selector和一组客户端套接字,负责读/写这些套接字。

© www.soinside.com 2019 - 2024. All rights reserved.