日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NIO核心框架介绍

發(fā)布時間:2023/12/10 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NIO核心框架介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?NIO共引入了4個概念:?
- 緩存區(qū):表示數(shù)據(jù)存放的容器,提供可讀寫的數(shù)據(jù)緩存區(qū);?
- 字符集:用來對緩存數(shù)據(jù)進行解碼和編碼,在字節(jié)和Unicode字符之間轉(zhuǎn)換;?
- 通道:用來接收或發(fā)送數(shù)據(jù),提供與文件、套接字等的連接,類似于Java IO中的流;?
- 選擇器:他們與可選擇通道一起定義了多路的、無阻塞的IO設(shè)施。?
NIO框架位于Java.nio包中,它為每一個概念都提供了核心的支持類:?
- 緩存區(qū)Buffer:包括ByteBuffer,Mapped?
- ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,ShortBuffer,IntBuffer,LongBuffer;?
- 字符集Charset:java.nio.charset包中定義了字符集API,包括字符集Charset,編碼器CharsetEncoder,解碼器CharsetDecoder;?
- 通道Channel:java.nio.channels包中定義了通道API,包括文件通道Filechannel,Socket通道SocketChannel,ServerSocket通道ServerSocketChannel,數(shù)據(jù)包通道DatagramChannel;?
- 選擇器Selector:包括選擇器Selector和事件對象SelectionKey。

下面來了解著4個概念的含義和作用,并了解各個類包的接口和類的使用:

1. 緩存區(qū)Buffer:?
???傳統(tǒng)的IO不斷浪費對象資源,NIO通過使用緩存區(qū)讀寫數(shù)據(jù)避免了資源浪費。緩存區(qū)是一個數(shù)據(jù)容器,就可以把它看作內(nèi)存中的一個大的數(shù)組,用來存放來自Channel的同一類型的所有數(shù)據(jù),因此我們可以使用字節(jié)、字符、整數(shù)等緩存區(qū)。字節(jié)緩存區(qū)提供必要的方法,可以提取或存入所有基本類型(boolean型除外)的數(shù)據(jù)。?
??每個非布爾基本類型都有一個緩存區(qū)類,包括ByteBuffer,MappedByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,ShortBuffer,IntBuffer,Longbuffer。每個類定義了一系列用于將數(shù)據(jù)移除或移入緩存區(qū)中g(shù)et()和put()方法,用于壓縮、復制和切片緩存區(qū)的方法,以及用于分配新緩存區(qū)和將現(xiàn)有數(shù)組包裝到緩存區(qū)中的靜態(tài)方法。?
??所有的緩存區(qū)類都有一個統(tǒng)一的抽象父類Buffer,它代表了一塊內(nèi)存區(qū)域,可以執(zhí)行一些與內(nèi)存有關(guān)的操作,如清除其中的內(nèi)容,支持讀寫或只讀等操作。該類提供了共有的4個屬性和3個操作。下面詳細看看這些屬性和操作的含義和使用方法,然后詳細了解8個實現(xiàn)類的使用。?
①Buffer緩存區(qū)的4個基本屬性:?
Buffer是個抽象類,它的基本屬性包括容量capacity、限制limit、位置position、標記mark。?
a、capacity:這個Buffer最多能放多少數(shù)據(jù),capacity一般在Buffer被創(chuàng)建的時候指定,取得容量的方法如下:

int capacity(); //返回此緩存區(qū)的容量

b、limit:在Buffer上進行的讀寫操作都不能越過這個下標。當寫數(shù)據(jù)到Buffer中時,limit一般和capacity相等,當讀數(shù)據(jù)時,limit代表Buffer中有效數(shù)據(jù)的長度,取得和修改限制的方法如下:

int limit();//返回此緩存區(qū)的限制 Buffer limit(int newLimit);//設(shè)置此緩存區(qū)的限制

c、position:讀寫操作的當前下標。當使用Buffer的相對位置進行讀寫操作時,讀寫會從這個下標進行,并在快操作完成后,Buffer會更新下標的值,取得和修改位置的方法如下:

int position(); //返回此緩存區(qū)的位置 BufferPosition(int newPosition);//設(shè)置此緩存區(qū)的位置

d、mark:一個臨時存放的位置下標。調(diào)用mark()會將mark設(shè)為當前的position值,以后調(diào)用reset()會將position屬性設(shè)置為mark的值。mark的值總是小雨等于position的值,如果將position的值設(shè)得比mark小,當前的mark值會被拋棄掉,可以使用下面的方法隨時設(shè)置一個標記:

Buffer mark();//在此緩存區(qū)的位置設(shè)置標記

這些屬性總是滿足以下條件:?
0<=mark<=position<=limit<=capacity?
因此,標記、位置、限制和容量值遵守以下不變式:?
0<=標記<=位置<=限制<=容量?
對初始化的Buffer來說,position為0,limit=capacity。?
②Buffer緩存區(qū)的3個數(shù)據(jù)操作:?
a、清除clear():把position設(shè)為0,把limit設(shè)為capacity,一般在把數(shù)據(jù)寫入Buffer前調(diào)用:

Buffer clear();//清除此緩存區(qū)

b、反轉(zhuǎn)flip():把limit設(shè)為當前position,把position設(shè)為0,一般在從Buffer讀取出數(shù)據(jù)前調(diào)用:

Buffer flip();//反轉(zhuǎn)此緩存區(qū)

c、重繞rewind():把position設(shè)為0,limit不變,一般在把數(shù)據(jù)重新寫入Buffer前調(diào)用

Buffer rewind();//重繞此緩存

Buffer對象有可能是只讀的,這時任何對該對象的寫操作都會觸發(fā)一個ReadOnlyBufferException。isReadOnly()方法可以用來判斷一個Buffer是否只讀。?
③Buffer緩存區(qū)的8個實現(xiàn)類:?
對于每個非boolean基本類型,都有一個Buffer子類與之對應,這些子類位于包java.nio.Buffer中,他們的類關(guān)系圖如下:?

2.字符集Charset——編碼與解碼?
??向ByteBuffer中存放數(shù)據(jù)涉及到兩個問題:字節(jié)的順序和字符轉(zhuǎn)換。ByteBuffer內(nèi)部通過ByteOrder類處理了字節(jié)順序問題,但是沒有處理字符轉(zhuǎn)換。事實上,ByteBuffer沒有提供讀寫String。?
??java.nio.charset.Charset處理了字符轉(zhuǎn)換問題。它通過構(gòu)造java.nio.charset.CharsetEncoder和java.nio.charset.CharsetDecoder將字符序列CharBuffer轉(zhuǎn)換成字節(jié)ByteBuffer和逆轉(zhuǎn)換。當需要將CharBuffer存放的數(shù)據(jù)編碼成ByteBuffer時,再將ByteBuffer里存的數(shù)據(jù)解碼成CharBuffer,這時候就要用到CharsetEncoder和CharsetDecoder了。?
??CharsetDecoder用來將ByteBuffer解碼為CharBuffer類型,CharsetEncoder用來將CharBuffer解碼為ByteBuffer類型,其中的編碼器和解碼器都是通過Charset來創(chuàng)建的,它們之間關(guān)系如下:?
?
3.通道Channel?
現(xiàn)有的java.io類中沒有能夠讀寫B(tài)uffer類型,所以NIO提供了Channel通道類來讀寫B(tài)uffer。Channel是一個連接,可用于接收或發(fā)送數(shù)據(jù),如文件和套接字。因為channel連接的是底層的物理設(shè)備,它可以直接支持設(shè)備的讀寫,或提供文件鎖。對于文件、管道、套接字都存在相應的Channel類。?
??可以把Channel看成是數(shù)據(jù)流的替代品,它還通過Selector和SelectableChannel這兩個類定義了一個進行非阻塞IO操作的API,這對需要高性能IO的應用非常重要。所有的Channel類都位于java.nio.channels包中,如下描述java.nio.channels中類和接口的關(guān)系:?
?
圖中最下面的4個類為具體的實現(xiàn)類。共包括7個接口類、3個抽象類和4個實現(xiàn)類。?
接口類:?
該圖中包含了一系列的接口,用以分別實現(xiàn)不同的功能封裝:?
①Channel是最頂層的接口,代表一個可以進行IO操作的通道;?
②ReadableByteChannel和WritableByteChannel分別提供對通道讀取和寫入ByteBuffer數(shù)據(jù)的功能;?
③ByteChannel用來將讀取和寫入的功能合并;?
④ScatteringByteChannel和GatheringByteChannel分別提供了批量讀取和寫入ByteBuffer數(shù)組的能力;?
⑤InterruptibleChannel提供多線程異步關(guān)閉的能力,它覆蓋了Channel接口中的關(guān)閉方法close(),這表現(xiàn)在兩方面:?
a、實現(xiàn)此接口的通道是可異步關(guān)閉的:如果某個線程阻塞于科終端通道上的IO操作,則另一個線程可調(diào)用該通道的close方法,這將導致已阻塞線程接收到AsynchronousCloseException,?
b、實現(xiàn)此接口的通道也是可中斷的:如果某個線程阻塞于科中斷通道上的IO操作中,則另一個線程可調(diào)用該阻塞線程的interrupt方法。這將導致該通道被關(guān)閉,已阻塞線程接收到CloseByInterruptException,并且設(shè)置阻塞線程的中斷狀態(tài)。?
??因此要擁有讀寫功能可以實現(xiàn)ByteChannel接口;要擁有批量讀寫功能,可以實現(xiàn)ScatteringByteChannel和GatheringByteChannel接口。從上圖可看出,FileChannel、DatagramChannel、SocketChannel實現(xiàn)了這3個接口,因此它們都擁有批量讀寫的功能。?
抽象類:?
①AbstractInterruptibleChannel提供了可中斷通道的基本實現(xiàn),該類封裝了實現(xiàn)通道異步關(guān)閉和中斷所需的最低級別機制。在調(diào)用可能無限期阻塞的IO操作之前和之后,具體的通道類必須分別調(diào)用begin()和end()方法;?
②SelectableChannel則提供了可通過Selector實現(xiàn)多路復用的通道:該抽象類是所有支持非阻塞IO操作的channel的父類。SelectableChannel可以通過register()方法注冊到一個或多個Selector,以進行非阻塞IO操作,此方法返回一個表示該通道已向選擇器注冊的心SelectionKey對象。SelectableChannel還可以選擇阻塞和非阻塞模式,這就是NIO非阻塞編程的核心。所有Channel創(chuàng)建的時候都是阻塞模式,只有非阻塞的SelectableChannel才可以參與非阻塞IO操作,可以使用下面方法來設(shè)置和查看阻塞模式:

SelectableChannel configureBlocking(boolean block); //設(shè)置blocking模式 boolean isBlocking(); //返回blocking模式

③AbstractSelectableChannel則提供了SelectableChannel中抽象函數(shù)的實現(xiàn)。此類定義了處理SelectableChannel通道注冊、注銷和關(guān)閉機制的各種方法。它會維持此通道的當前阻塞模式及其當前的選擇鍵集。;?
這三級抽象類都實現(xiàn)了InterruptibleChannel接口,所以也擁有多線程下異步關(guān)閉的能力。

轉(zhuǎn)發(fā):https://blog.csdn.net/luliuliu1234/article/details/61915000

總結(jié)

以上是生活随笔為你收集整理的NIO核心框架介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。