反應堆模式是一種對象行爲類的設計模式,對同步事件分揀和派發。它是處理併發I/O比較常見的一種模式,用於同步I/O。html
其中心思想是將全部要處理的I/O事件註冊到一箇中心I/O多路複用器上,同時主線程阻塞在多路複用器上;一旦有I/O事件到來或者是準備就緒,多路複用器返回並將相應的I/O事件分發到對應的處理器中。react
Reactor是一種事件驅動機制,和普通函數的不一樣之處在於:應用程序不是主動的調用某個API完成處理,Reactor逆置了事件處理流程,應用程序須要提供相應的接口並註冊到Reactor上,若是相應的時間發生,Reactor將主動調用應用程序註冊的接口(這些接口又被稱爲"回調函數")。下面是事件驅動機制的模型圖:設計模式
事件驅動(回調)就是應用業務向一箇中間人註冊一個回調(event handler),當I/O就緒後,就向這個中間人產生一個事件,並通知此handler進行處理。這個中間人是由一個不斷等待和循環的單獨線程來承擔,它接受全部的handler的註冊,並負責向操做系統查詢IO是否就緒在就緒後就調用指定的handler進行處理。這個中間人的名字就就叫作Reactor。數組
Reactor模式是編寫高性能網絡服務器的必備技術,主要有如下優勢:服務器
Handler表明操做系統管理的資源,包括:網絡鏈接、打開的文件、同步對象等等。事件能夠來自外部,如客戶端的鏈接請求、數據等,也能夠來自內部,如定時器事件。網絡
由操做系統提供的I/O多路複用機制,例如select和epoll,程序首先將其關心的句柄(即事件源)及其事件註冊到event demultiplexer上,當有事件到達時,event demultiplexer會發出通知「在已經註冊的句柄集中,一個或者多個句柄的事件已經就緒」;程序收到通知後,就能夠在非阻塞的狀況下對事件進行處理了。多線程
一個或多個模板函數組成的接口,描述了和應用程序相關的對某個事件的操做併發
事件處理接口的實現,實現了應用程序提供的某個服務函數
定義了一些接口,用於應用程序控制事件調度,以及應用程序註冊、刪除事件處理器和相關的描述符,是事件處理器的調度核心。Reactor管理器使用同步事件分離器來等待事件的發生。一旦事件發生,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(); } }