上圖是NIO的線程模型, 基於select實現, 這種線程模型的特色: 多條channel經過一個選擇器和單挑線程綁定, 而且在這種編程模型中, Channel中相關業務邏輯不容許存在耗時的任務 , 若是必定會有耗時的邏輯, 請將它們放置到線程池中去運行, 由於這種模型雖然作到了非阻塞, 可是他並非真正的異步編程, 任何channel上的任何耗時的操做, 都會拖垮這個選擇器, 進而拖垮整條線程 , 這也是爲啥它會被稱爲 同步非阻塞java
select()
會同步等待選擇器感興趣的事件發生NIO線程線程模型相對於傳統的BIO來講, 最大的優點就是在於 NIO線程模型中單條線程可同時爲N個用戶(Channel)服務, 而BIO編程模型讓人詬病的地方就是, 任何一個新鏈接接入, 服務器都得爲他開啓不止一條新的線程去運行它, 這種BIO系統中, 併發確定不會很高編程
NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持服務器
AIO是(jdk1.7) 發行的 異步IO編程模型, 真正實現了異步IO, 基於Linux系統的 Epoll 機制實現網絡
不管是NIO, 仍是AIO底層都沒有改變網絡通訊的基本步驟, 而是在這個基礎上進行了一系列的升級架構
AIO的底層實現是由操做系統完成的, 數據在內核空間&用戶空間的遷移, 咱們在編寫代碼時也是這樣, 只須要調用 AIO.read()
或者是 AIO.write()
便可, 換句話說, 咱們的業務邏輯就成了 回調, 原來在操做系統處理數據的這個過程當中, 咱們的程序須要阻塞等待着, 亦或者放在線程池中運行, 而在AIO編程中這段等待時間差被省去了, 由於當操做系統認爲數據還有沒準備完時, 它是不會打擾咱們的程序的, 這時咱們的程序能夠去處理其餘的邏輯, 而一旦操做系統認爲數據齊全了, 他就會回調咱們的提供的回調函數併發
下面貼出來一個AIO編程Server端的實例:異步
像下面的 read() write() accept() 全是異步的, 一經調用即刻返回, 不同的地方是咱們會提供一個回調對象, 留給操做系統, 當操做系統認爲讀寫數據都到位了, 就會去回調這些函數async
public class AIOServer { private ExecutorService executorService; // 服務端的Channel private AsynchronousServerSocketChannel asynchronousServerSocketChannel; private AIOServer(int port) { init(port); } // 初始化 private void init(int port) { System.out.println("aio server start with port " + port); executorService = Executors.newFixedThreadPool(5); try { // 開啓服務端的通道 asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open(); // 綁定端口 asynchronousServerSocketChannel.bind(new InetSocketAddress(port)); System.out.println("server start ... "); /** * 方法會異步的去接收一個請求, accept()一樣是 * 參數1 : this , 暫時理解成任意類型的 * 參數2 : CompleteHandler -- 當請求到來後,會交付給 AIOServerHandler進行處理 * * todo 在 AIO中的監聽並非while(true), 而是相似遞歸的操做, 每次監聽到客戶端的請求後, 都須要在處理邏輯中開啓下一次的監聽 */ asynchronousServerSocketChannel.accept(this, new AIOServerHandler()); System.out.println("------------------------------"); // 阻塞程序 try { TimeUnit.SECONDS.sleep(60); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } public AsynchronousServerSocketChannel getAsynchronousServerSocketChannel() { return this.asynchronousServerSocketChannel; } public static void main(String[] args) { AIOServer aioServer = new AIOServer(9999); } }
AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。異步編程
我是bloger 賜我白日夢, 歡迎關注我 --武漢加油函數