1、舉例說明html
假設你是一個老師,讓30個學生解答一道題目,而後檢查學生作的是否正確,你有下面幾個選擇:react
1. 第一種選擇: 按順序逐個檢查,先檢查A,而後是B,以後是C、D。。。這中間若是有一個學生卡主,全班都會被耽誤。技術上的問題,是將IO操做中等待和非等待的部分分開處理。咱們都知道IO操做分爲兩個部分:
一、等待數據就緒
二、處理數據多線程
衆所周知的幾種IO模型(阻塞、非阻塞、多路複用、信號驅動、異步)就是區別於這兩個階段,當須要處理不少鏈接的時候(高併發的狀況),容易想到的是使用多線程技術,好比最簡單的One-connection-Per-thread模式,可是由於等待數據不可避免,形成的結果是線程不停的休眠-喚醒的切換,致使CPU不堪重負。併發
IO複用的目的:將這兩個階段分開處理,讓一個線程(並且是內核級別的線程)來處理全部的等待,一旦有相應的IO事件發生就通知繼續完成IO操做,雖然仍然有阻塞和等待,可是等待老是發生在一個線程,這時使用多線程能夠保證其餘線程一旦喚醒就是處理數據,固然這須要非阻塞IO API的支持(好比非阻塞套接字)。Linux2.6以前的select,poll以及以後的epoll都是IO複用技術的實現。select和poll基本一致,epoll是對它們的改進版本。但總的來講它們都還不是真正的異步IO,由於它們在IO讀寫的時候仍然是阻塞的、同步的(完成一件過後才能作另一件事)。異步IO是指「處理數據」這一階段也是非阻塞的。Windows上的IOCP(完成端口)纔是真正的AIO,理論上它比Linux的epoll更先進。框架
至於select、poll和epoll的區別,推薦這篇文章:http://www.cnblogs.com/Anker/p/3265058.html。簡單來講:select,poll無腦的輪詢,忽略了高併發下,輪詢自己成了瓶頸,而epoll使用回調實現了輪詢真正須要處理的鏈接。異步
Reactor模式是爲了咱們更簡單的使用IO複用技術。它是一種併發IO模式,其餘的模式還有多進程,多線程等。Reactor自己也有不少變種,好比thread per request,worker thread,thread pool,multiple reactors...網上這方面的資料不少。雖然網上關於reactor和多線程模孰優孰劣還有爭論(Reactor最明顯的一個缺點是沒法充分利用多核的優點),可是大部分高併發的框架或組建都是基於reactor的,好比MINA,Netty,再好比Redis,Nginx(有多個工做進程來充分利用多核的優點)。關於Java中的IO複用能夠看Doug Lea大神的Scalable IO in Java(http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf)。socket