真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

nioJAVA代碼 nio代碼示例

什么是NIO框架?

Java NIO框架MINA用netty性能和鏈接數(shù)、并發(fā)等壓力測試參數(shù)好于mina。\x0d\x0a\x0d\x0a特點:\x0d\x0a1。NIO彌補了原來的I/O的不足,它再標準java代碼中提供了高速和面向塊的I/O\x0d\x0a原力的I/O庫與NIO最重要的區(qū)別是數(shù)據(jù)打包和傳輸方式的不同,原來的I/O以流的方式處理數(shù)據(jù),而NIO以塊的方式處理數(shù)據(jù);\x0d\x0a\x0d\x0a2.NIO以通道channel和緩沖區(qū)Buffer為基礎(chǔ)來實現(xiàn)面向塊的IO數(shù)據(jù)處理,MINA是開源的。\x0d\x0a\x0d\x0aJavaNIO非堵塞應(yīng)用通常適用用在I/O讀寫等方面,我們知道,系統(tǒng)運行的性能瓶頸通常在I/O讀寫,包括對端口和文件的操作上,過去,在打開一個I/O通道后,read()將一直等待在端口一邊讀取字節(jié)內(nèi)容,如果沒有內(nèi)容進來,read()也是傻傻的等,這會影響我們程序繼續(xù)做其他事情,那么改進做法就是開設(shè)線程,讓線程去等待,但是這樣做也是相當耗費資源的。\x0d\x0a\x0d\x0aJava NIO非堵塞技術(shù)實際是采取Reactor模式,或者說是Observer模式為我們監(jiān)察I/O端口,如果有內(nèi)容進來,會自動通知我們,這樣,我們就不必開啟多個線程死等,從外界看,實現(xiàn)了流暢的I/O讀寫,不堵塞了。\x0d\x0a\x0d\x0aJava NIO出現(xiàn)不只是一個技術(shù)性能的提高,會發(fā)現(xiàn)網(wǎng)絡(luò)上到處在介紹它,因為它具有里程碑意義,從JDK1.4開始,Java開始提高性能相關(guān)的功能,從而使得Java在底層或者并行分布式計算等操作上已經(jīng)可以和C或Perl等語言并駕齊驅(qū)。\x0d\x0a\x0d\x0a如果至今還是在懷疑Java的性能,說明思想和觀念已經(jīng)完全落伍了,Java一兩年就應(yīng)該用新的名詞來定義。從JDK1.5開始又要提供關(guān)于線程、并發(fā)等新性能的支持,Java應(yīng)用在游戲等適時領(lǐng)域方面的機會已經(jīng)成熟,Java在穩(wěn)定自己中間件地位后,開始蠶食傳統(tǒng)C的領(lǐng)域。\x0d\x0a\x0d\x0a原理:\x0d\x0aNIO 有一個主要的類Selector,這個類似一個觀察者,只要我們把需要探知socketchannel告訴Selector,我們接著做別的事情,當有事件發(fā)生時,他會通知我們,傳回一組SelectionKey,我們讀取這些Key,就會獲得我們剛剛注冊過的socketchannel,然后,我們從這個Channel中讀取數(shù)據(jù),放心,包準能夠讀到,接著我們可以處理這些數(shù)據(jù)。Selector內(nèi)部原理實際是在做一個對所注冊的channel的輪詢訪問,不斷的輪詢(目前就這一個算法),一旦輪詢到一個channel有所注冊的事情發(fā)生。比如數(shù)據(jù)來了,他就會站起來報告,交出一把鑰匙,讓我們通過這把鑰匙來讀取這個channel的內(nèi)容。在使用上,也在分兩個方向,一個是線程處理,一個是用非線程,后者比較簡單。

十載的日照網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整日照建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)建站從事“日照網(wǎng)站設(shè)計”,“日照網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

java nio 開發(fā)實例

首先了解下所謂的java nio是個什么東西!

傳統(tǒng)的并發(fā)型服務(wù)器設(shè)計是利用阻塞型網(wǎng)絡(luò)I/O 以多線程的模式來實現(xiàn)的 然而由

于系統(tǒng)常常在進行網(wǎng)絡(luò)讀寫時處于阻塞狀態(tài) 會大大影響系統(tǒng)的性能 自Java 開始引入

了NIO(新I/O) API 通過使用非阻塞型I/O 實現(xiàn)流暢的網(wǎng)絡(luò)讀寫操作 為開發(fā)高性能并發(fā)

型服務(wù)器程序提供了一個很好的解決方案 這就是java nio

首先來看下傳統(tǒng)的阻塞型網(wǎng)絡(luò) I/O的不足

Java 平臺傳統(tǒng)的I/O 系統(tǒng)都是基于Byte(字節(jié))和Stream(數(shù)據(jù)流)的 相應(yīng)的I/O 操

作都是阻塞型的 所以服務(wù)器程序也采用阻塞型I/O 進行數(shù)據(jù)的讀 寫操作 本文以TCP

長連接模式來討論并發(fā)型服務(wù)器的相關(guān)設(shè)計 為了實現(xiàn)服務(wù)器程序的并發(fā)性要求 系統(tǒng)由一

個單獨的主線程來監(jiān)聽用戶發(fā)起的連接請求 一直處于阻塞狀態(tài) 當有用戶連接請求到來時

程序都會啟一個新的線程來統(tǒng)一處理用戶數(shù)據(jù)的讀 寫操作

這種模式的優(yōu)點是簡單 實用 易管理 然而缺點也是顯而易見的 由于是為每一個客

戶端分配一個線程來處理輸入 輸出數(shù)據(jù) 其線程與客戶機的比例近似為 隨著線程

數(shù)量的不斷增加 服務(wù)器啟動了大量的并發(fā)線程 會大大加大系統(tǒng)對線程的管理開銷 這將

成為吞吐量瓶頸的主要原因 其次由于底層的I/O 操作采用的同步模式 I/O 操作的阻塞管

理粒度是以服務(wù)于請求的線程為單位的 有可能大量的線程會閑置 處于盲等狀態(tài) 造成I/O

資源利用率不高 影響整個系統(tǒng)的性能

對于并發(fā)型服務(wù)器 系統(tǒng)用在阻塞型I/O 等待和線程間切換的時間遠遠多于CPU 在內(nèi)

存中處理數(shù)據(jù)的時間 因此傳統(tǒng)的阻塞型I/O 已經(jīng)成為制約系統(tǒng)性能的瓶頸 Java 版本

后推出的NIO 工具包 提供了非阻塞型I/O 的異步輸入輸出機制 為提高系統(tǒng)的性能提供

了可實現(xiàn)的基礎(chǔ)機制

NIO 包及工作原理

針對傳統(tǒng)I/O 工作模式的不足 NIO 工具包提出了基于Buffer(緩沖區(qū)) Channel(通

道) Selector(選擇器)的新模式 Selector(選擇器) 可選擇的Channel(通道)和

SelectionKey(選擇鍵)配合起來使用 可以實現(xiàn)并發(fā)的非阻塞型I/O 能力

NIO 工具包的成員

Buffer(緩沖器)

Buffer 類是一個抽象類 它有 個子類分別對應(yīng)于七種基本的數(shù)據(jù)類型 ByteBuffer

CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer 和ShortBuffer 每一個Buffer

對象相當于一個數(shù)據(jù)容器 可以把它看作內(nèi)存中的一個大的數(shù)組 用來存儲和提取所有基本

類型(boolean 型除外)的數(shù)據(jù) Buffer 類的核心是一塊內(nèi)存區(qū) 可以直接對其執(zhí)行與內(nèi)存有關(guān)

的操作 利用操作系統(tǒng)特性和能力提高和改善Java 傳統(tǒng)I/O 的性能

Channel(通道)

Channel 被認為是NIO 工具包的一大創(chuàng)新點 是(Buffer)緩沖器和I/O 服務(wù)之間的通道

具有雙向性 既可以讀入也可以寫出 可以更高效的傳遞數(shù)據(jù) 我們這里主要討論

ServerSocketChannel 和SocketChannel 它們都繼承了SelectableChannel 是可選擇的通道

分別可以工作在同步和異步兩種方式下(這里的可選擇不是指可以選擇兩種工作方式 而是

指可以有選擇的注冊自己感興趣的事件) 當通道工作在同步方式時 它的功能和編程方法

與傳統(tǒng)的ServerSocket Socket 對象相似 當通道工作在異步工作方式時 進行輸入輸出處

理不必等到輸入輸出完畢才返回 并且可以將其感興趣的(如 接受操作 連接操作 讀出

操作 寫入操作)事件注冊到Selector 對象上 與Selector 對象協(xié)同工作可以更有效率的支

持和管理并發(fā)的網(wǎng)絡(luò)套接字連接

Selector(選擇器)和SelectionKey(選擇鍵)

各類 Buffer 是數(shù)據(jù)的容器對象 各類Channel 實現(xiàn)在各類Buffer 與各類I/O 服務(wù)間傳輸

數(shù)據(jù) Selector 是實現(xiàn)并發(fā)型非阻塞I/O 的核心 各種可選擇的通道將其感興趣的事件注冊

到Selector 對象上 Selector 在一個循環(huán)中不斷輪循監(jiān)視這各些注冊在其上的Socket 通道

SelectionKey 類則封裝了SelectableChannel 對象在Selector 中的注冊信息 當Selector 監(jiān)測

到在某個注冊的SelectableChannel 上發(fā)生了感興趣的事件時 自動激活產(chǎn)生一個SelectionKey

對象 在這個對象中記錄了哪一個SelectableChannel 上發(fā)生了哪種事件 通過對被激活的

SelectionKey 的分析 外界可以知道每個SelectableChannel 發(fā)生的具體事件類型 進行相應(yīng)的

處理

NIO 工作原理

通過上面的討論 我們可以看出在并發(fā)型服務(wù)器程序中使用NIO 實際上是通過網(wǎng)絡(luò)事

件驅(qū)動模型實現(xiàn)的 我們應(yīng)用Select 機制 不用為每一個客戶端連接新啟線程處理 而是將

其注冊到特定的Selector 對象上 這就可以在單線程中利用Selector 對象管理大量并發(fā)的網(wǎng)

絡(luò)連接 更好的利用了系統(tǒng)資源 采用非阻塞I/O 的通信方式 不要求阻塞等待I/O 操作完

成即可返回 從而減少了管理I/O 連接導(dǎo)致的系統(tǒng)開銷 大幅度提高了系統(tǒng)性能

當有讀或?qū)懙热魏巫缘氖录l(fā)生時 可以從Selector 中獲得相應(yīng)的

SelectionKey 從SelectionKey 中可以找到發(fā)生的事件和該事件所發(fā)生的具體的

SelectableChannel 以獲得客戶端發(fā)送過來的數(shù)據(jù) 由于在非阻塞網(wǎng)絡(luò)I/O 中采用了事件觸

發(fā)機制 處理程序可以得到系統(tǒng)的主動通知 從而可以實現(xiàn)底層網(wǎng)絡(luò)I/O 無阻塞 流暢地讀

寫 而不像在原來的阻塞模式下處理程序需要不斷循環(huán)等待 使用NIO 可以編寫出性能更

好 更易擴展的并發(fā)型服務(wù)器程序

并發(fā)型服務(wù)器程序的實現(xiàn)代碼

應(yīng)用 NIO 工具包 基于非阻塞網(wǎng)絡(luò)I/O 設(shè)計的并發(fā)型服務(wù)器程序與以往基于阻塞I/O 的

實現(xiàn)程序有很大不同 在使用非阻塞網(wǎng)絡(luò)I/O 的情況下 程序讀取數(shù)據(jù)和寫入數(shù)據(jù)的時機不

是由程序員控制的 而是Selector 決定的 下面便給出基于非阻塞網(wǎng)絡(luò)I/O 的并發(fā)型服務(wù)器

程序的核心代碼片段

import java io * //引入Java io包

import * //引入包

import java nio channels * //引入Java nio channels包

import java util * //引入Java util包

public class TestServer implements Runnable

{

/**

* 服務(wù)器Channel對象 負責(zé)接受用戶連接

*/

private ServerSocketChannel server

/**

* Selector對象 負責(zé)監(jiān)控所有的連接到服務(wù)器的網(wǎng)絡(luò)事件的發(fā)生

*/

private Selector selector

/**

* 總的活動連接數(shù)

*/

private int activeSockets

/**

* 服務(wù)器Channel綁定的端口號

*/

private int port

/**

*

* 構(gòu)造函數(shù)

*/

public TestServer()throws IOException

{

activeSockets=

port= //初始化服務(wù)器Channel綁定的端口號為

selector= Selector open() //初始化Selector對象

server=ServerSocketChannel open() //初始化服務(wù)器Channel對象

ServerSocket socket=server socket() //獲取服務(wù)器Channel對應(yīng)的//ServerSocket對象

socket bind(new InetSocketAddress(port)) //把Socket綁定到監(jiān)聽端口 上

nfigureBlocking(false) //將服務(wù)器Channel設(shè)置為非阻塞模式

server register(selector SelectionKey OP_ACCEPT) //將服務(wù)器Channel注冊到

Selector對象 并指出服務(wù)器Channel所感興趣的事件為可接受請求操作

}

public void run()

{

while(true)

{

try

{

/**

*應(yīng)用Select機制輪循是否有用戶感興趣的新的網(wǎng)絡(luò)事件發(fā)生 當沒有

* 新的網(wǎng)絡(luò)事件發(fā)生時 此方法會阻塞 直到有新的網(wǎng)絡(luò)事件發(fā)生為止

*/

selector select()

}

catch(IOException e)

{

continue //當有異常發(fā)生時 繼續(xù)進行循環(huán)操作

}

/**

* 得到活動的網(wǎng)絡(luò)連接選擇鍵的集合

*/

SetSelectionKey keys=selector selectedKeys()

activeSockets=keys size() //獲取活動連接的數(shù)目

if(activeSockets== )

{

continue //如果連接數(shù)為 則繼續(xù)進行循環(huán)操作

}

/**

/**

* 應(yīng)用For—Each循環(huán)遍歷整個選擇鍵集合

*/

for(SelectionKey key :keys)

{

/**

* 如果關(guān)鍵字狀態(tài)是為可接受 則接受連接 注冊通道 以接受更多的*

事件 進行相關(guān)的服務(wù)器程序處理

*/

if(key isAcceptable())

{

doServerSocketEvent(key)

continue

}

/**

* 如果關(guān)鍵字狀態(tài)為可讀 則說明Channel是一個客戶端的連接通道

* 進行相應(yīng)的讀取客戶端數(shù)據(jù)的操作

*/

if(key isReadable())

{

doClientReadEvent(key)

continue

}

/**

* 如果關(guān)鍵字狀態(tài)為可寫 則也說明Channel是一個客戶端的連接通道

* 進行相應(yīng)的向客戶端寫數(shù)據(jù)的操作

*/

if(key isWritable())

{

doClinetWriteEvent(key)

continue

}

}

}

}

/**

* 處理服務(wù)器事件操作

* @param key 服務(wù)器選擇鍵對象

*/

private void doServerSocketEvent(SelectionKey key)

{

SocketChannel client=null

try

{

ServerSocketChannel server=(ServerSocketChannel)key channel()

client=server accept()

if(client==null)

{

return

}

nfigureBlocking(false) //將客戶端Channel設(shè)置為非阻塞型

/**

/**

* 將客戶端Channel注冊到Selector對象上 并且指出客戶端Channel所感

* 興趣的事件為可讀和可寫

*/

client register(selector SelectionKey OP_READ|SelectionKey OP_READ)

}catch(IOException e)

{

try

{

client close()

}catch(IOException e ){}

}

}

/**

* 進行向客戶端寫數(shù)據(jù)操作

* @param key 客戶端選擇鍵對象

*/

private void doClinetWriteEvent(SelectionKey key)

{

代碼實現(xiàn)略

}

/**

* 進行讀取客戶短數(shù)據(jù)操作

* @param key 客戶端選擇鍵對象

*/

private void doClientReadEvent(SelectionKey key)

{

代碼實現(xiàn)略

}

}

從上面對代碼可以看出 使用非阻塞性I/O進行并發(fā)型服務(wù)器程序設(shè)計分三個部分

向Selector對象注冊感興趣的事件 從Selector中獲取所感興趣的事件 根據(jù)不同的事件進

行相應(yīng)的處理

結(jié)語

通過使用NIO 工具包進行并發(fā)型服務(wù)器程序設(shè)計 一個或者很少幾個Socket 線程就可

以處理成千上萬個活動的Socket 連接 大大降低了服務(wù)器端程序的開銷 同時網(wǎng)絡(luò)I/O 采取

非阻塞模式 線程不再在讀或?qū)憰r阻塞 操作系統(tǒng)可以更流暢的讀寫數(shù)據(jù)并可以更有效地向

CPU 傳遞數(shù)據(jù)進行處理 以便更有效地提高系統(tǒng)的性能

看到這里相信你看了不止 分鐘了吧 ? 我說 分鐘其實就是想讓大家能夠輕松的讀下去(雞蛋 )

好了 到這里大家應(yīng)該對java nio有個初步的了解了吧~~~

lishixinzhi/Article/program/Java/hx/201311/27190

sun.nio包是什么,是java代碼么

nio是針對原java io所開發(fā)的一套新的io api接口。 Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API,可以替代標準的Java IO API。

Java NIO怎么理解通道和非阻塞

nio引入了buffer、channel、selector等概念。

通道相當于之前的I/O流。

“通道”太抽象了。java解釋不清的東西只能看它底層是怎么解釋的——操作系統(tǒng)的I/O控制,通道控制方式?

I/O設(shè)備:CPU——通道——設(shè)備控制器——I/O設(shè)備

(通道和設(shè)備控制器的關(guān)系是多對多,設(shè)備控制器和I/O設(shè)備的關(guān)系也是多對多。)

I/O過程,參考;DMA.htm:

1.CPU在執(zhí)行用戶程序時遇到I/O請求,根據(jù)用戶的I/O請求生成通道程序(也可以是事先編好的)。放到內(nèi)存中,并把該通道程序首地址放入CAW中。

2.CPU執(zhí)行“啟動I/O”指令,啟動通道工作。

3.通道接收“啟動I/O”指令信號,從CAW(記錄下一條通道指令存放的地址)中取出通道程序首地址,并根據(jù)此地址取出通道程序的第一條指令,放入CCW(記錄正在執(zhí)行的通道指令)中;同時向CPU發(fā)回答信號,通知“啟動I/O”指令完成完畢,CPU可繼續(xù)執(zhí)行。

4.與此同時,通道開始執(zhí)行通道程序,進行物理I/O操作。當執(zhí)行完一條指令后,如果還有下一條指令則繼續(xù)執(zhí)行;否則表示傳輸完成,同時自行停止,通知CPU轉(zhuǎn)去處理通道結(jié)束事件,并從CCW中得到有關(guān)通道狀態(tài)。

如此一來,主處理器只要發(fā)出一個I/O操作命令,剩下的工作完全由通道負責(zé)。I/O操作結(jié)束后,I/O通道會發(fā)出一個中斷請求,表示相應(yīng)操作已完成。

通道控制方式是對數(shù)據(jù)塊進行處理的,并非字節(jié)。

通道控制方式就是異步I/O

I/O分兩段:1.數(shù)據(jù)從I/O設(shè)備到內(nèi)核緩沖區(qū)。2.數(shù)據(jù)從內(nèi)核緩沖區(qū)到應(yīng)用緩沖區(qū)

I/O類型:

1.異步I/O不會產(chǎn)生阻塞,程序不會等待I/O完成,繼續(xù)執(zhí)行代碼,等I/O完成了再執(zhí)行一個什么回調(diào)函數(shù),代碼執(zhí)行效率高。很容易聯(lián)想到ajax。這個一般用于I/O操作不影響之后的代碼執(zhí)行。

2.阻塞I/O,程序發(fā)起I/O操作后,進程阻塞,CPU轉(zhuǎn)而執(zhí)行其他進程,I/O的兩個步驟完成后,向CPU發(fā)送中斷信號,進程就緒,等待執(zhí)行。

3.非阻塞I/O并非都不阻塞,其實是第一步不阻塞,第二部阻塞。程序發(fā)起I/O操作后,進程一直檢查第一步是否完成,CPU一直在循環(huán)詢問,完成后,進程阻塞直到完成第二步。明白了!這個是“站著茅坑不拉屎”,CPU利用率最低的。邏輯和操作系統(tǒng)的程序直接控制方式一樣。

阻塞不阻塞描述的是發(fā)生I/O時當前線程的狀態(tài)。

以上是操作系統(tǒng)的I/O,那么java的nio又是怎樣的呢?

個人覺得是模仿了通道控制方式。

先看看nio的示例代碼:

服務(wù)端TestReadServer.java

import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class TestReadServer { /*標識數(shù)字*/ private int flag = 0; /*緩沖區(qū)大小*/ private int BLOCK = 1024*1024*10; /*接受數(shù)據(jù)緩沖區(qū)*/ private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*發(fā)送數(shù)據(jù)緩沖區(qū)*/ private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); private Selector selector; public TestReadServer(int port) throws IOException { // 打開服務(wù)器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 服務(wù)器配置為非阻塞 serverSocketChannel.configureBlocking(false); // 檢索與此通道關(guān)聯(lián)的服務(wù)器套接字 ServerSocket serverSocket = serverSocketChannel.socket(); // 進行服務(wù)的綁定 serverSocket.bind(new InetSocketAddress(port)); // 通過open()方法找到Selector selector = Selector.open(); // 注冊到selector,等待連接 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server Start----"+port+":"); } // 監(jiān)聽 private void listen() throws IOException { while (true) { // 選擇一組鍵,并且相應(yīng)的通道已經(jīng)打開 selector.select(); // 返回此選擇器的已選擇鍵集。 SetSelectionKey selectionKeys = selector.selectedKeys(); IteratorSelectionKey iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); handleKey(selectionKey); } } } // 處理請求 private void handleKey(SelectionKey selectionKey) throws IOException { // 接受請求 ServerSocketChannel server = null; SocketChannel client = null; String receiveText; String sendText; int count=0; // 測試此鍵的通道是否已準備好接受新的套接字連接。 if (selectionKey.isAcceptable()) { // 返回為之創(chuàng)建此鍵的通道。 server = (ServerSocketChannel) selectionKey.channel(); // 接受到此通道套接字的連接。 // 此方法返回的套接字通道(如果有)將處于阻塞模式。 client = server.accept(); // 配置為非阻塞 client.configureBlocking(false); // 注冊到selector,等待連接 client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { // 返回為之創(chuàng)建此鍵的通道。 client = (SocketChannel) selectionKey.channel(); //將緩沖區(qū)清空以備下次讀取 receivebuffer.clear(); //讀取服務(wù)器發(fā)送來的數(shù)據(jù)到緩沖區(qū)中 System.out.println(System.currentTimeMillis()); count = client.read(receivebuffer); System.out.println(System.currentTimeMillis() + "~"+count); } } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub int port = 1234; TestReadServer server = new TestReadServer(port); server.listen(); } }客戶端TestReadClient.javaimport java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class TestReadClient { /*標識數(shù)字*/ private static int flag = 0; /*緩沖區(qū)大小*/ private static int BLOCK = 1024*1024*10; /*接受數(shù)據(jù)緩沖區(qū)*/ private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK); /*發(fā)送數(shù)據(jù)緩沖區(qū)*/ private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK); /*服務(wù)器端地址*/ private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress( "localhost", 1234); public static void main(String[] args) throws IOException { // TODO Auto-generated method stub // 打開socket通道 SocketChannel socketChannel = SocketChannel.open(); // 設(shè)置為非阻塞方式 socketChannel.configureBlocking(false); // 打開選擇器 Selector selector = Selector.open(); // 注冊連接服務(wù)端socket動作 socketChannel.register(selector, SelectionKey.OP_CONNECT); // 連接 socketChannel.connect(SERVER_ADDRESS); // 分配緩沖區(qū)大小內(nèi)存 SetSelectionKey selectionKeys; IteratorSelectionKey iterator; SelectionKey selectionKey; SocketChannel client; String receiveText; String sendText; int count=0; while (true) { //選擇一組鍵,其相應(yīng)的通道已為 I/O 操作準備就緒。 //此方法執(zhí)行處于阻塞模式的選擇操作。 selector.select(); //返回此選擇器的已選擇鍵集。 selectionKeys = selector.selectedKeys(); //System.out.println(selectionKeys.size()); iterator = selectionKeys.iterator(); while (iterator.hasNext()) { selectionKey = iterator.next(); if (selectionKey.isConnectable()) { System.out.println("client connect"); client = (SocketChannel) selectionKey.channel(); // 判斷此通道上是否正在進行連接操作。 // 完成套接字通道的連接過程。 if (client.isConnectionPending()) { client.finishConnect(); System.out.println("完成連接!"); sendbuffer.clear(); BufferedInputStream br = new BufferedInputStream(new FileInputStream(new File("D:\BigData.zip"))); byte[] b = new byte[BLOCK]; br.read(b); sendbuffer.put(b); sendbuffer.flip(); System.out.println(System.currentTimeMillis()); client.write(sendbuffer); System.out.println(System.currentTimeMillis()); } client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { client = (SocketChannel) selectionKey.channel(); //將緩沖區(qū)清空以備下次讀取 receivebuffer.clear(); //讀取服務(wù)器發(fā)送來的數(shù)據(jù)到緩沖區(qū)中 count=client.read(receivebuffer); if(count0){ receiveText = new String( receivebuffer.array(),0,count); System.out.println("客戶端接受服務(wù)器端數(shù)據(jù)--:"+receiveText); client.register(selector, SelectionKey.OP_WRITE); } } } selectionKeys.clear(); } } }例子是TestReadClient向TestReadServer發(fā)送一個本地文件。TestReadServer收到后每次打印讀取到的字節(jié)數(shù)。

如何體現(xiàn)異步I/O?

看看TestReadClient中的:

if (selectionKey.isConnectable()) { System.out.println("client connect"); client = (SocketChannel) selectionKey.channel(); // 判斷此通道上是否正在進行連接操作。 // 完成套接字通道的連接過程。 if (client.isConnectionPending()) { client.finishConnect();如果沒有client.finishConnect();這句等待完成socket連接,可能會報異常:java.nio.channels.NotYetConnectedException

異步的才不會管你有沒有連接成功,都會執(zhí)行下面的代碼。這里需要人為的干預(yù)。

如果要證明是java的nio單獨使用非阻塞I/O,真沒辦法?。?!阻塞非阻塞要查看進程。。。

不過還有種說法,叫異步非阻塞。上面那段,是用異步方式創(chuàng)建連接,進程當然沒有被阻塞。使用了finishConnect()這是人為將程序中止,等待連接創(chuàng)建完成(是模仿阻塞將當前進程阻塞掉,還是模仿非阻塞不斷輪詢訪問,不重要了反正是程序卡住沒往下執(zhí)行)。

所以,創(chuàng)建連接的過程用異步非阻塞I/O可以解釋的通。那read/write的過程呢?

根據(jù)上面例子的打印結(jié)果,可以知道這個過程是同步的,沒執(zhí)行完是不會執(zhí)行下面的代碼的。至于底下是使用阻塞I/O還是非阻塞I/O,對于應(yīng)用級程序來說不重要了。

阻塞還是非阻塞,對于正常的開發(fā)(創(chuàng)立連接,從連接中讀寫數(shù)據(jù))并沒有多少的提升,操作過程都類似。

那NIO憑什么成為高性能架構(gòu)的基礎(chǔ),比起IO,性能優(yōu)越在哪里,接著猜。。。

java nio有意模仿操作系統(tǒng)的通道控制方式,那他的底層是不是就是直接使用操作系統(tǒng)的通道?

通道中的數(shù)據(jù)是以塊為單位的,之前的流是以字節(jié)為單位的,同樣的數(shù)據(jù)流操作外設(shè)的次數(shù)較多。代碼中channel都是針對ByteBuffer對象進行read/write的,而ByteBuffer又是ByteBuffer.allocate(BLOCK);這樣創(chuàng)建的,是一個連續(xù)的塊空間。

那ByteBuffer是不是也是模擬操作系統(tǒng)的緩存?

緩存在io也有,如BufferedInputStream。CPU和外設(shè)的速度差很多,緩存為了提高CPU使用率,等外設(shè)將數(shù)據(jù)讀入緩存后,CPU再統(tǒng)一操作,不用外設(shè)讀一次,CPU操作一次,CPU的效率會被拉下來。。。


文章名稱:nioJAVA代碼 nio代碼示例
文章鏈接:http://weahome.cn/article/ddogipj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部