反应堆模式
一、概念
1、定义
反应堆模式是一种对象行为类的设计模式,对同步事件分拣和派发。它是处理并发I/O比较常见的一种模式,用于同步I/O。
其中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上;一旦有I/O事件到来或者是准备就绪,多路复用器返回并将相应的I/O事件分发到对应的处理器中。
2、Reactor事件处理机制
Reactor是一种事件驱动机制,和普通函数的不同之处在于:应用程序不是主动的调用某个API完成处理,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的时间发生,Reactor将主动调用应用程序注册的接口(这些接口又被称为"回调函数")。下面是事件驱动机制的模型图:
事件驱动(回调)就是应用业务向一个中间人注册一个回调(event handler),当I/O就绪后,就向这个中间人产生一个事件,并通知此handler进行处理。这个中间人是由一个不断等待和循环的单独线程来承担,它接受所有的handler的注册,并负责向操作系统查询IO是否就绪在就绪后就调用指定的handler进行处理。这个中间人的名字就就叫做Reactor。
3、优点
Reactor模式是编写高性能网络服务器的必备技术,主要有以下优点:
- 相应快,不必为单个同步事件所阻塞,虽然Reactor本身也是同步的
- 避免了多线程/进程的的切换开销
- 可扩展性,可以方便的通过增加Reactor实例个数来充分利用CPU资源
二、反应堆模式组成
1、Handler事件源
Handler代表操作系统管理的资源,包括:网络连接、打开的文件、同步对象等等。事件可以来自外部,如客户端的连接请求、数据等,也可以来自内部,如定时器事件。
2、Synchronous event demultiplexer同步事件分离器(事件多路分发机制)
由操作系统提供的I/O多路复用机制,例如select和epoll,程序首先将其关心的句柄(即事件源)及其事件注册到event demultiplexer上,当有事件到达时,event demultiplexer会发出通知“在已经注册的句柄集中,一个或者多个句柄的事件已经就绪”;程序收到通知后,就可以在非阻塞的情况下对事件进行处理了。
3、event Handler事件处理接口
一个或多个模板函数组成的接口,描述了和应用程序相关的对某个事件的操作
4、concrete event Handler具体的事件处理器
事件处理接口的实现,实现了应用程序提供的某个服务
5、Reactor反应器
定义了一些接口,用于应用程序控制事件调度,以及应用程序注册、删除事件处理器和相关的描述符,是事件处理器的调度核心。Reactor管理器使用同步事件分离器来等待事件的发生。一旦事件发生,Reactor管理器先是分离每个事件,然后调度事件处理器,最后调用相关的模 板函数来处理这个事件。
三、NIO中的Reactor模式
NIO中Reactor的核心是Selector。下面是一个简单的示例:
public class Reactor implements Runnable { Selector selector; public Reactor() throws IOException { selector = Selector.open(); } public void run() { try { while (!Thread.interrupted()) { // 循环,等待事件 selector.select(); Set selected = selector.selectedKeys(); Iterator it = selected.iterator(); while (it.hasNext()) // 调用handler,处理事件 dispatch((SelectionKey) (it.next())); selected.clear(); } } catch (IOException ex) { /* ... */ } } void dispatch(SelectionKey k) { Runnable r = (Runnable) (k.attachment()); if (r != null) r.run(); } }