Java NIO教程 前言
NIO 是 New I/O 的縮寫,要了解它真正的內(nèi)涵,需要掌握的知識還是比較多的。我努力在這幾篇筆記里,勾勒出整個io的面貌。為大家的深入學(xué)習(xí)鋪路。
I/O簡史想理解I/O的全部,java的I/O歷史是必須要了解的。java的I/O歷史也從一個側(cè)面反應(yīng)了java的發(fā)展史。
JDK1.0-1.3在這個時期的java中,基本上可以說沒有完整的I/O支持。因為這一時期的java I/O操作是阻塞的,所以I/O效率是較為底下的,基本上想要有比較好的I/O解決方案,基本靠自己。這時期java在服務(wù)器端一直沒有得到重用,和糟糕的I/O效率是有很大的關(guān)系的。不但I/O弄的不好,而且一系列周邊措施都沒弄好。所支持的字符集編碼有限,經(jīng)常要進行手工的編碼工作。而且沒有正則表達式,處理數(shù)據(jù)十分困難。
JDK1.4-1.62002年發(fā)布的java1.4中,非阻塞I/O以JSR-51的身份加入到j(luò)ava語言中。同時字符集的編解碼能力大大提升。而且有了基于perl實現(xiàn)的正則表達式類庫。同時部分舊I/O底層實現(xiàn),也用新I/O的方式重寫,使得舊I/O的性能也有了提升。終于java在服務(wù)器端開始流行了起來。
與此同時,第三方也開始發(fā)力。谷歌發(fā)布了Guava類庫,其中的I/O部分,極大的簡化了一些文件的操作和數(shù)據(jù)的傳輸。同時Trustin Lee領(lǐng)導(dǎo)編寫的nio框架netty與mina也廣為流傳開來,這對java nio的發(fā)展業(yè)是有著極大的推動力的。
JDK1.7至今隨著JSR-203的推出,是我們在java1.7中見到了NIO2。它為我們提供了必非阻塞更加強大的異步I/O操作能力,同時提供了一系列極為方便的對文件系統(tǒng)和文件屬性進行操作的API。以及更加強大的網(wǎng)絡(luò)I/O
I/O區(qū)別阻塞I/O、非阻塞I/O、異步I/O之間到底有什么區(qū)別?為什么每一次的進步,都會促使java I/O能力的極大提升?我們舉一個種菜游戲的例子。
假如有一個種菜游戲(就跟之前的QQ農(nóng)場類似),在玩家種菜以后,必須一直呆在那個網(wǎng)頁上,看著菜成熟,才可以收菜。這是極其浪費時間的,用戶體驗也一定不會好。這個游戲后來進行了改版,玩家種菜之后不用再一直停留在那個網(wǎng)頁上了,只是需要時不時來看一遍,如果某一次查看時發(fā)現(xiàn)菜成熟了,就可以收菜了。當(dāng)然,用戶體驗極大的提升了,用戶所浪費的時間也減少了,但是為了更加提升用戶體驗,游戲又進行了改版。玩家種菜之后,不用再查看菜是否成熟了,等到菜成熟后,該游戲會自動給用戶發(fā)送一個通知,告訴他,菜已成熟、趕緊來收。這樣用戶的基本上再也不用浪費時間了。
剛剛例子中的三個游戲版本,代表了三種I/O。阻塞I/O:在數(shù)據(jù)沒有讀寫完成之前,CPU不可以進行下一步操作,這樣CPU只好眼睜睜的在那里傻等。非阻塞I/O:在數(shù)據(jù)沒有讀寫完成之前,CPU可以離開,只需要每隔一段時間詢問一次。異步I/O:在數(shù)據(jù)沒有讀寫完成之前,CPU可以離開也不用時不時的關(guān)心一下I/O,在數(shù)據(jù)讀寫完成時,主動通知CPU。三種I/O之間的效率,高低立判。
新I/O咱們以java1.4所提出的非阻塞I/O,為切入點,開始了解全貌。
ChannelsBuffersSelectors這三個類構(gòu)成了非阻塞I/O的核心API。
Buffer譯為緩存區(qū),它是一塊可以存儲數(shù)據(jù)的內(nèi)存。Channel有點像流,但它可讀可寫、從本地I/O到網(wǎng)絡(luò)I/O都可以,絕大多數(shù)NIO都從一個Channel開始的,數(shù)據(jù)可以從Channel讀到Buffer中,也可以從Buffer 寫到Channel中。非阻塞I/O中,CPU可以在數(shù)據(jù)沒有讀寫完成之前離開,只需要每隔一段時間詢問一次。詢問數(shù)據(jù)是否讀寫完成,需要的CPU能力是極小的,但如果CPU經(jīng)常切換任務(wù)所需要的保留現(xiàn)場和恢復(fù)現(xiàn)場的時間是較大的。所以可以就用一個線程來詢問數(shù)據(jù)是否準(zhǔn)備好。一個線程在多個通道內(nèi)詢問數(shù)據(jù)是否準(zhǔn)備好,就需要管理多個通道的方式,這就是
。使用Selector,得向Selector注冊Channel,然后調(diào)用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件。
說了這么多,我們該從什么地方開始呢? 咱們從java7的新文件系統(tǒng)開始吧
相關(guān)文章:
1. 如何基于Python Matplotlib實現(xiàn)網(wǎng)格動畫2. 利用promise及參數(shù)解構(gòu)封裝ajax請求的方法3. ASP 信息提示函數(shù)并作返回或者轉(zhuǎn)向4. asp(vbs)Rs.Open和Conn.Execute的詳解和區(qū)別及&H0001的說明5. ThinkPHP5實現(xiàn)JWT Token認證的過程(親測可用)6. Ajax實現(xiàn)表格中信息不刷新頁面進行更新數(shù)據(jù)7. JSP數(shù)據(jù)交互實現(xiàn)過程解析8. windows服務(wù)器使用IIS時thinkphp搜索中文無效問題9. .NET中l(wèi)ambda表達式合并問題及解決方法10. PHP設(shè)計模式中工廠模式深入詳解
