1 / 41

New I/O Features of JDK1.4

New I/O Features of JDK1.4. Try NCCU Computer Center May 29,2002. 參考資料. [1]David Flanagan, “ Top Ten Cool New Features of Java 2 SE 1.4 ” ,onjava.com,Mar 2002 [2]Mark Reinhold, ” JSR51:New I/O APIs for the Java Platform ” ,http://jcp.org/jsr/detail/051.prt,May 2002

fergal
Download Presentation

New I/O Features of JDK1.4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. New I/O Features of JDK1.4 Try NCCU Computer Center May 29,2002

  2. 參考資料 • [1]David Flanagan,“Top Ten Cool New Features of Java 2 SE 1.4” ,onjava.com,Mar 2002 • [2]Mark Reinhold,”JSR51:New I/O APIs for the Java Platform”,http://jcp.org/jsr/detail/051.prt,May 2002 • [3]Java 2 Standard Editon Java API Document, http://java.sun.com/j2se/1.4/docs/api/index.html • [4]John Zukowski,”New I/O Functionality for Java 2 Standard Edition 1.4”,Sun,Oct 2001 • [5]Source Code of JDK 1.4.0 • [6]Tim Burns,”Non-Blocking Socket I/O in JDK1.4”,Owl Mountain Software ,LLC,Dec 2001 • [7]Elliotte Rusty Harold,”Java Network Programming”,O’reilly,Dec 1997

  3. Presentation Conventions • 解說內文儘可能完全用中文來表達。 • 專業術語則完全用原文(from jjhou)。 • 能用圖表達的就不用文字。

  4. Presentation Agenda • 簡介 • NIO API的新功能 • Buffer家族 • Channel家族 • File System I/O (File Channel) • Selector觀念 • Network I/O (Socket Channel)

  5. 簡介 • 規格來源為JSR51-New I/O APIs for the Java Platform。 • 初版通過:2000/1/20。 • 為何制定新的API? • 回應外界對I/O效能的批評。 • 回應外界要求的 (原來OS的native api有、Java platform卻沒有)新功能。

  6. 簡介(2) • JDK1.4十大新功能排名,I/O相關分佔第二(regular expression)、三(non-blocking)及第四名(file channel)。 • 舊I/O API目前並沒有deprecated的計畫。但JSP51中還是建議開發人員改用新的API來開發。

  7. 新的I/O 需求(JSR 51) • 新的API必須要有擴充性(Scalable),且支援polling(輪詢)及asynchronous request(如Non-blocking)。 • 可以將File System上的檔案map到程式可直接存取的記憶體位址上。這項功能必須由下層的作業系統直接支援。 • 更快速的Binary I/O及Character I/O API。 • Character I/O API要能支援regular expressions。

  8. NIO API的新功能 • 效能提升 • 在很多API的實作過程很有技巧地使用native code(nio.dll)所以nio的實作會依平台的不同而不同,JDK的提供者負擔變多。 • 犧牲部份的簡單性換取效能大幅的進展。 • Channel-Buffer互相配合的運作機制 • 舊io:stream-oriented,新io:block-oriented。 • DirectBuffer • 直接在System Buffer上與底層os互動。

  9. 一般Buffer

  10. DirectBuffer

  11. 新的I/O運作機制 • 新的I/O運作機制由「Channel-Buffer」合作完成I/O動作。 • InputStream/OutputStream是單向,Channel是雙向。 • Stream每次讀寫1byte,Channel每次讀寫「1 chunk of data」 • 這「1 chunk of data」指的就是Buffer! • 由Channel進行的I/O,一定都是透過Buffer。

  12. NIO 與 IO的相容性 • 其實部份舊I/O的類別已被重新改寫成底層使用Channel機制。如 • FileInputStream/FileOutputStream/RandomAccessFile • Socket/ServerSocket/DatagramSocket 以上這些類別都有getChannel()方法。 • 所以就算是用舊的API,也有可能不知不覺已用到了新的API功能。

  13. Buffer家族 • Buffer類別是學習nio的基礎。 • Buffer是一個新類別,直接extend Object。 • 以Buffer為祖先,extend下來的有ByteBuffer、CharBuffer、IntBuffer、…..。 • 這些xxxBuffer之中,xxx都是「基本型別」,所以像java.lang.StringBuffer和目前我們要討論的Buffer家族一點關係都沒有。 • 每一個基本類別都有一個xxxBuffer與之對應。 • 要存取Channel,一定要透過Buffer。

  14. Buffer家族(2)

  15. Buffer是什麼 • Buffer是一組資料形成的序列,這些序列都是由基本型別所構成。 (JavaDoc) • Buffer = 定義了屬於Buffer的特徵及行為 • ByteBuffer = byte陣列 +屬於Buffer的特徵及行為 + 專屬ByteBuffer的特徵及行為 • CharBuffer = char陣列 +屬於Buffer的特徵及行為 + 專屬CharBuffer的特徵及行為 • 其它類別以此類推。

  16. 建構Buffer實體的方法 • 向系統要求5bytes的記憶體。 • ByteBuffer buf = ByteBuffer.allocate(5); • ByteBuffer.allocate(5)做了什麼事? • return new HeapByteBuffer(5, 5); • 向系統要求5bytes的DirectBuffer。 • ByteBuffer buf = ByteBuffer.allocateDirect(5); • 什麼是DirectBuffer??

  17. DirectByteBuffer • DirectByteBuffer同時extend 自MappedByteBuffer及implement DirectBuffer這個interface。 • 呼叫ByteBuffer.allocateDirect(5)時發生了什麼事? • Return new DirectByteBuffer(5) • 呼叫unsafe.allocateMemory() • unsafe.allocateMemory()實作在JVM中,其實就是呼叫malloc()來配置記憶體。 • unsafe.setMemory(),初始化記憶體。

  18. DirectByteBuffer(2) • 所以allocateDirect是透過JNI直接呼叫作業系統的system call來配置記憶體。 • Unsafe類別實作在JVM中,包裝了一系列低階、不安全的method,是一個final 類別。 • 由於必須透過JNI,所以呼叫次數太多反而導致效能降低。JavaDoc上的建議是那種一次allocate大一個,然後會存在很久的Buffer用DirectBuffer比較划算。

  19. Channel觀念 (以下摘自Channel之JavaDoc) • I/O 動作的核心(nexus of I/O)。 • 一個 channel 代表一個連到特定裝置的連結(connection),例如file或 a network socket。 • Channel只有二種狀態, open 或 closed。 • Channel closed之後,去對這個Channel做任何I/O動作都會導致ClosedChannelException。

  20. Channel家族

  21. File System I/O 的流程 • 利用FileInputStream讀入檔案。 • 利用FileInputStream的getChannel()方法得到一個FileChannel。 • 利用FileChannel的read()方法將檔案由channel讀到buffer中。 • 大部份的情況下buffer比File size小,所以要讀很多次。 • 再依據一般操作Buffer的方式來操作即可。 • 最後記得呼叫channel的close()。

  22. 在螢幕上印出一個File的content String fileName = “data.txt"; FileInputStream fis = new FileInputStream(fileName); FileChannel channel = fis.getChannel(); ByteBuffer buf = ByteBuffer.allocate(10); while(channel.read(buf)>0) { buf.flip(); byte[] b = new byte[buf.limit()]; buf.get(b); System.out.print(new String(b)); buf.clear(); } channel.close();

  23. File System I/O 的流程(map) • 利用FileInputStream讀入檔案。 • 利用FileInputStream的getChannel()方法得到一個FileChannel。 • 利用FileChannel的map()方法將檔案map到記憶體中,所得結果存入MappedByteBuffer中。 • 再依據一般操作Buffer的方式來操作即可。 • 最後記得呼叫channel的close()。

  24. 在螢幕上印出一個File的content(map) String fileName = "data.txt"; FileInputStream fis = new FileInputStream(fileName); FileChannel channel = fis.getChannel(); MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY,0,channel.size()); byte[] b = new byte[(int)channel.size()]; buf.get(b); System.out.print(new String(b)); channel.close();

  25. File locking • 為了避免multithread運作時的檔案存取問題,可以針對File做Lock的機制。 • 可以只針對某個檔案的特定區段做Lock • 比如我們要從檔案的第10個字元lock到第30個字元,一共lock 20個字的區段,就可以寫成如下 • FileLock lock = somFileChannel.lock(10,20,true); • 其中第三個參數如果是true代表是shared lock,如果是false代表exclusive lock。

  26. 深入FileChannel的map() • MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) • map方法中做了些什麼? • 檢查所傳入mode、position、size的正確性。 • 透過windows API取得SYSTEMINFO結構中的allocationGranularity • 計算pagePosition = position%allocationGranularity

  27. 深入FileChannel的map() • 根據pagePosition調整所要map的範圍 • (new postion = position - pagePosition ) • (new size = size + pagePosition ) • 調整後呼叫Native call -- map0() • Win API:CreateFileMapping()—得到Mapping Object 之Handle • Win API:MapViewOfFile()—得到Mapping Object之Address • 得到位址後,呼叫Util.newMappedByteBuffer(),其實它就是直接幫我們new了一個DirectByteBuffer。 • 接下來把這個DirectByteBuffer回傳就大功告成!!

  28. Non-Blocking I/O的運作方式 • 送出資料後,不用一直等,可以先做別的事。有回應時系統會藉由Selector機制通知。 • 首先要利用Channel的configureBlocking()方法,告訴系統我們要用NonBlocking的方式。 • 再來向Selector註冊Channel及我們有興趣的事件。當事件發生時,Selector就會通知我們,並傳回一組SelectionKey(Set類別)。 • 這些key有一個method叫channel(),我們從這個method就可以再度取我們剛註冊的channel,並加以處理了。

  29. while (selector.select(500) > 0) { Set readyKeys = selector.selectedKeys(); //取得SelectionKeys Iterator readyItor = readyKeys.iterator(); while (readyItor.hasNext()) { SelectionKey key = (SelectionKey)readyItor.next(); readyItor.remove();//務必記得這一行 SocketChannel keyChannel = (SocketChannel)key.channel(); if (key.isConnectable()) {//在這裏處理OP_CONNECT事件 } else if (key.isReadable()) {//在這裏處理OP_READ事件 } } }

  30. Selector觀念 • Selector在Non-Blocking中扮演關鍵性的角色。 • (參考Channel類別圖)SelectableChannel的子類別都有一個method叫register()。透過這個method,可以向Selector註冊我們有興趣的事件。

  31. Selector和SelectorProvider • Selector本身是一個abstract類別。 • 在實作上,為了可以支援多種不同的Selector,所以在這裏使用Factory Pattern。 • SelectorProvider = Creator。 • Selector = Product。 • PollSelectorImpl = ConcreteProduct。 • PollSelectorProvider = ConcreteCreator。

  32. Factory Pattern

  33. Selector繼承關係

  34. SelectorProvider繼承關係

  35. 觀察Selector的建造過程 • Selector selector = Selector.open(); • open()方法內部: • SelectorProvider.provider().openSelector(); • SelectorProvider.provider()方法運作方式。 • 檢查系統參數之中是否有java.nio.channels.spi.SelectorProvider = ????這個參數。 • 如果有,就load該class來當做Selector。 • 如果沒有就load「DefaultSelectorProvider」,其實就是「PollSelectorProvider」。

  36. Selector的selector方法探討 • 如何偵測有事件發生 while(selector.select(500)>0) { ......(do something)... } //註:selector是一個Selector的instance • selector.select(500)的傳回值大於0就是有我們註冊的事發生了。 • select()的傳回值是什麼意義? • select(500)中的500又是什麼意義呢?

  37. Selector的selector方法探討(2) • select()的傳回值代表的是傳回所得到SelectionKey的數目。 • select()中的參數代表timeout。

  38. 追蹤PollSelector的select()方法 • pollSelector.select(500) • doSelect(500) • pollWrapper.poll() //Native call • (Win API) WSAWaitForMultipleEvent() • 追蹤後發現這個數字被原封不動地傳到底層的Win API,所以這個500的數字的意義等同於WSAWaitForMultipleEvent()的第四個參數。 • 也就是說timeout後,若wait的對象(channel)沒有回應,這個Win API就傳回WSA_WAIT_TIMEOUT。 • 在Java上來看,它會傳回0,並直接進行下一行。

  39. 如何設定no timeout • 前面說我們的timeout參數會被原封不動傳到底層,這裏有一項例外,就是當我們的timeout是傳0時。 • 它會將0改成-1,再呼叫doSelect() • 傳到pollWrapper.poll()時,就會判斷 if (timeout < 0) { timeout = WSA_INFINITE; } • 所以傳0代表的意義是永遠沒有timeout,一直等下去。 • 也可以直接呼叫select(),它其實就是等同於select(0)

  40. Summary • Java.nio這個package最引人注目的新功能就是號稱效能上的改善及non-blocking的支援。 • 另外還有對regular expression的支援未介紹。 • 針對NIO,SUN所提供的文件不夠多,java doc上的解釋也不夠詳盡,導致developer被迫要讀source code。 • 為了避免日後程式碼所用的api被deprecate,建議日後還是用nio的方式寫I/O程式。

  41. Q & A

More Related