我正在使用Reactor Pattern
使用java NIO编写一个简单的服务器应用程序。据我了解,Reactor
类负责收集Events
(例如:OP_ACCEPT,OP_READ,OP_WRITE)。
相对EventHandler
将负责特定任务。因此处理程序应该能够异步运行在不同的线程中。
当我运行它时,它显示一些问题,while循环继续运行,Selector
保持返回readyOps设置为(1,4,16)。我猜是因为AcceptHanndler
没有以阻止的方式处理OP_ACCEPT
。因此,即使从迭代器中删除密钥,在select()
调用之后,它也会再次出现。
我不能在单独的线程中将eventHander作为runnable运行吗?
我想到了edge-triggered
和level-triggered
模型的概念。原因是选择器是在level-triggered
模型中运行吗?
答案 0 :(得分:2)
是的,选择器是水平触发的。您的案例中的标准工作流将遵循:在您检测到该通道可接受之后,从Selector中取消该键,并且仅在将该键传递给事件处理程序线程之后。事件处理程序线程将完成接受并且1)再次为OP_ACCEPT注册服务器套接字; 2)根据您要实现的协议,为OP_READ和/或OP_WRITE注册接受的客户端套接字。或者,您可以在主线程中完成接受(出于性能原因,如果有一大堆连接客户端)。
实际上,按操作类型区分线程是不可扩展的,并且由于数据局部性差,可能在SMP系统中性能较差。最好将每个客户端套接字锁定到单个线程。高性能Java服务器通常通过使一个线程专门用于接受(仅在那里注册单个ServerSocket)和N个工作线程来实现客户端套接字来实现。接受线程在循环中工作:
每个工作线程都有自己的Selector和一组客户端套接字,负责读/写这些套接字。