在學習Java I/O類庫時泰鸡,容易混淆NIO、BIO壳鹤、AIO這幾個概念盛龄,同時對于阻塞和非阻塞、同步和異步的理解也較為晦澀芳誓,這篇文章是對這幾個概念的一些區(qū)分以及個人的一些見解余舶。
一、同步阻塞I/O(BIO):
同步阻塞I/O锹淌,服務器實現(xiàn)模式為一個連接一個線程匿值,即客戶端有連接請求時服務器就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷赂摆,可以通過線程池機制來改善挟憔。BIO方式適用于連接數(shù)目比較小且固定的架構,這種方式對服務端資源要求比較高烟号,并發(fā)局限于應用中绊谭,在jdk1.4以前是唯一的io現(xiàn)在,但程序直觀簡單易理解
二汪拥、同步非阻塞I/O(NIO):
同步非阻塞I/O达传,服務器實現(xiàn)模式為一個請求一個線程,即客戶端發(fā)送的連接請求都會注冊到多路復用器上迫筑,多路復用器輪詢到連接有IO請求時才啟動一個線程進行處理宪赶。NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構,比如聊天服務器铣焊,并發(fā)局限于應用中逊朽,編程比較復雜,jdk1,4開始支持
三曲伊、異步非阻塞I/O(AIO):
異步非阻塞I/O,服務器實現(xiàn)模式為一個有效請求一個線程,客戶端的IO請求都是由操作系統(tǒng)先完成了再通知服務器用其啟動線程進行處理坟募。AIO方式適用于連接數(shù)目多且連接比較長(重操作)的架構岛蚤,比如相冊服務器,充分調(diào)用OS參與并發(fā)操作懈糯,編程比較復雜涤妒,jdk1.7開始支持。
四赚哗、IO與NIO區(qū)別:
IO面向流她紫,NIO面向緩沖區(qū)
IO的各種流是阻塞的,NIO是非阻塞模式
Java NIO的選擇允許一個單獨的線程來監(jiān)視多個輸入通道屿储,可以注冊多個通道使用一個選擇器贿讹,然后使用一個單獨的線程來“選擇”通道:這些通道里已經(jīng)有可以處理的輸入或選擇已準備寫入的通道。這種選擇機制够掠,使得一個單獨的線程很容易來管理多個通道
五民褂、同步與異步的區(qū)別:
同步:發(fā)送一個請求,等待返回疯潭,再發(fā)送下一個請求赊堪,同步可以避免出現(xiàn)死鎖,臟讀的發(fā)生
異步:發(fā)送一個請求竖哩,不等待返回哭廉,隨時可以再發(fā)送下一個請求,可以提高效率相叁,保證并發(fā)
同步異步關注點在于消息通信機制群叶,
阻塞與非阻塞關注的是程序在等待調(diào)用結(jié)果時(消息、返回值)的狀態(tài):
阻塞調(diào)用是指調(diào)用結(jié)果返回之前钝荡,當前線程會被掛起街立。調(diào)用線程只有在得到結(jié)果之后才會返回。
非阻塞調(diào)用指在不能立刻得到結(jié)果之前埠通,該調(diào)用不會阻塞當前線程
不同層次:
CPU層次:操作系統(tǒng)進行IO或任務調(diào)度層次赎离,現(xiàn)代操作系統(tǒng)通常使用異步非阻塞方式進行IO(有少部分IO可能會使用同步非阻塞),即發(fā)出IO請求后端辱,并不等待IO操作完成梁剔,而是繼續(xù)執(zhí)行接下來的指令(非阻塞),IO操作和CPU指令互不干擾(異步)舞蔽,最后通過中斷的方式通知IO操作的完成結(jié)果荣病。
線程層次:操作系統(tǒng)調(diào)度單元的層次,操作系統(tǒng)為了減輕程序員的思考負擔渗柿,將底層的異步非阻塞的IO方式進行封裝个盆,把相關系統(tǒng)調(diào)用(如read和write)以同步的方式展現(xiàn)出來脖岛,然而同步阻塞IO會使線程掛起,同步非阻塞IO會消耗CPU資源在輪詢上颊亮,3個解決方法柴梆;
多線程(同步阻塞)
IO多路復用(select、poll终惑、epoll)
直接暴露出異步的IO接口绍在,kernel-aio和IOCP(異步非阻塞)
Linux IO模型:
阻塞/非阻塞:等待I/O完成的方式,阻塞要求用戶程序停止執(zhí)行雹有,直到IO完成偿渡,而非阻塞在IO完成之前還可以繼續(xù)執(zhí)行
同步/異步:獲知IO完成的方式,同步需要時刻關心IO是否完成霸奕,異步無需主動關心溜宽,在IO完成時它會收到通知