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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java NIO原理 图文分析及代码实现

發(fā)布時(shí)間:2025/6/15 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java NIO原理 图文分析及代码实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在分析hadoop的RPC(Remote Procedure Call Protocol ,遠(yuǎn)程過(guò)程調(diào)用協(xié)議,它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。可以參考:http://baike.baidu.com/view/32726.htm?)機(jī)制時(shí),發(fā)現(xiàn)hadoop的RPC機(jī)制的實(shí)現(xiàn)主要用到了兩個(gè)技術(shù):動(dòng)態(tài)代理(動(dòng)態(tài)代理可以參考博客:http://weixiaolu.iteye.com/blog/1477774?)和java NIO。為了能夠正確地分析hadoop的RPC源碼,我覺(jué)得很有必要先研究一下java NIO的原理和具體實(shí)現(xiàn)。

這篇博客我主要從兩個(gè)方向來(lái)分析java NIO

目錄:
一.java NIO 和阻塞I/O的區(qū)別
???? 1. 阻塞I/O通信模型
???? 2. java NIO原理及通信模型
二.java NIO服務(wù)端和客戶端代碼實(shí)現(xiàn)
?

具體分析:?

一.java NIO 和阻塞I/O的區(qū)別?

1. 阻塞I/O通信模型
?

假如現(xiàn)在你對(duì)阻塞I/O已有了一定了解,我們知道阻塞I/O在調(diào)用InputStream.read()方法時(shí)是阻塞的,它會(huì)一直等到數(shù)據(jù)到來(lái)時(shí)(或超時(shí))才會(huì)返回;同樣,在調(diào)用ServerSocket.accept()方法時(shí),也會(huì)一直阻塞到有客戶端連接才會(huì)返回,每個(gè)客戶端連接過(guò)來(lái)后,服務(wù)端都會(huì)啟動(dòng)一個(gè)線程去處理該客戶端的請(qǐng)求。阻塞I/O的通信模型示意圖如下:

?

?

如果你細(xì)細(xì)分析,一定會(huì)發(fā)現(xiàn)阻塞I/O存在一些缺點(diǎn)。根據(jù)阻塞I/O通信模型,我總結(jié)了它的兩點(diǎn)缺點(diǎn):
1. 當(dāng)客戶端多時(shí),會(huì)創(chuàng)建大量的處理線程。且每個(gè)線程都要占用棧空間和一些CPU時(shí)間

2. 阻塞可能帶來(lái)頻繁的上下文切換,且大部分上下文切換可能是無(wú)意義的。

在這種情況下非阻塞式I/O就有了它的應(yīng)用前景。

2.?
java NIO原理及通信模型?

Java NIO是在jdk1.4開(kāi)始使用的,它既可以說(shuō)成“新I/O”,也可以說(shuō)成非阻塞式I/O。下面是java NIO的工作原理:

1. 由一個(gè)專門的線程來(lái)處理所有的 IO 事件,并負(fù)責(zé)分發(fā)。?
2. 事件驅(qū)動(dòng)機(jī)制:事件到的時(shí)候觸發(fā),而不是同步的去監(jiān)視事件。?
3. 線程通訊:線程之間通過(guò) wait,notify 等方式通訊。保證每次上下文切換都是有意義的。減少無(wú)謂的線程切換。?

閱讀過(guò)一些資料之后,下面貼出我理解的java NIO的工作原理圖:

?

?

(注:每個(gè)線程的處理流程大概都是讀取數(shù)據(jù)、解碼、計(jì)算處理、編碼、發(fā)送響應(yīng)。)

Java NIO的服務(wù)端只需啟動(dòng)一個(gè)專門的線程來(lái)處理所有的 IO 事件,這種通信模型是怎么實(shí)現(xiàn)的呢?呵呵,我們一起來(lái)探究它的奧秘吧。java NIO采用了雙向通道(channel)進(jìn)行數(shù)據(jù)傳輸,而不是單向的流(stream),在通道上可以注冊(cè)我們感興趣的事件。一共有以下四種事件:

?

事件名對(duì)應(yīng)值
服務(wù)端接收客戶端連接事件SelectionKey.OP_ACCEPT(16)
客戶端連接服務(wù)端事件SelectionKey.OP_CONNECT(8)
讀事件SelectionKey.OP_READ(1)
寫事件SelectionKey.OP_WRITE(4)

?

??
??
??
??
??

服務(wù)端和客戶端各自維護(hù)一個(gè)管理通道的對(duì)象,我們稱之為selector,該對(duì)象能檢測(cè)一個(gè)或多個(gè)通道 (channel) 上的事件。我們以服務(wù)端為例,如果服務(wù)端的selector上注冊(cè)了讀事件,某時(shí)刻客戶端給服務(wù)端發(fā)送了一些數(shù)據(jù),阻塞I/O這時(shí)會(huì)調(diào)用read()方法阻塞地讀取數(shù)據(jù),而NIO的服務(wù)端會(huì)在selector中添加一個(gè)讀事件。服務(wù)端的處理線程會(huì)輪詢地訪問(wèn)selector,如果訪問(wèn)selector時(shí)發(fā)現(xiàn)有感興趣的事件到達(dá),則處理這些事件,如果沒(méi)有感興趣的事件到達(dá),則處理線程會(huì)一直阻塞直到感興趣的事件到達(dá)為止。下面是我理解的java NIO的通信模型示意圖:

?

?

二.java NIO服務(wù)端和客戶端代碼實(shí)現(xiàn)?

為了更好地理解java NIO,下面貼出服務(wù)端和客戶端的簡(jiǎn)單代碼實(shí)現(xiàn)。

服務(wù)端:

?

Java代碼??
  • package?cn.nio;??
  • ??
  • 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.ServerSocketChannel;??
  • import?java.nio.channels.SocketChannel;??
  • import?java.util.Iterator;??
  • ??
  • /**?
  • ?*?NIO服務(wù)端?
  • ?*?@author?小路?
  • ?*/??
  • public?class?NIOServer?{??
  • ????//通道管理器??
  • ????private?Selector?selector;??
  • ??
  • ????/**?
  • ?????*?獲得一個(gè)ServerSocket通道,并對(duì)該通道做一些初始化的工作?
  • ?????*?@param?port??綁定的端口號(hào)?
  • ?????*?@throws?IOException?
  • ?????*/??
  • ????public?void?initServer(int?port)?throws?IOException?{??
  • ????????//?獲得一個(gè)ServerSocket通道??
  • ????????ServerSocketChannel?serverChannel?=?ServerSocketChannel.open();??
  • ????????//?設(shè)置通道為非阻塞??
  • ????????serverChannel.configureBlocking(false);??
  • ????????//?將該通道對(duì)應(yīng)的ServerSocket綁定到port端口??
  • ????????serverChannel.socket().bind(new?InetSocketAddress(port));??
  • ????????//?獲得一個(gè)通道管理器??
  • ????????this.selector?=?Selector.open();??
  • ????????//將通道管理器和該通道綁定,并為該通道注冊(cè)SelectionKey.OP_ACCEPT事件,注冊(cè)該事件后,??
  • ????????//當(dāng)該事件到達(dá)時(shí),selector.select()會(huì)返回,如果該事件沒(méi)到達(dá)selector.select()會(huì)一直阻塞。??
  • ????????serverChannel.register(selector,?SelectionKey.OP_ACCEPT);??
  • ????}??
  • ??
  • ????/**?
  • ?????*?采用輪詢的方式監(jiān)聽(tīng)selector上是否有需要處理的事件,如果有,則進(jìn)行處理?
  • ?????*?@throws?IOException?
  • ?????*/??
  • ????@SuppressWarnings("unchecked")??
  • ????public?void?listen()?throws?IOException?{??
  • ????????System.out.println("服務(wù)端啟動(dòng)成功!");??
  • ????????//?輪詢?cè)L問(wèn)selector??
  • ????????while?(true)?{??
  • ????????????//當(dāng)注冊(cè)的事件到達(dá)時(shí),方法返回;否則,該方法會(huì)一直阻塞??
  • ????????????selector.select();??
  • ????????????//?獲得selector中選中的項(xiàng)的迭代器,選中的項(xiàng)為注冊(cè)的事件??
  • ????????????Iterator?ite?=?this.selector.selectedKeys().iterator();??
  • ????????????while?(ite.hasNext())?{??
  • ????????????????SelectionKey?key?=?(SelectionKey)?ite.next();??
  • ????????????????//?刪除已選的key,以防重復(fù)處理??
  • ????????????????ite.remove();??
  • ????????????????//?客戶端請(qǐng)求連接事件??
  • ????????????????if?(key.isAcceptable())?{??
  • ????????????????????ServerSocketChannel?server?=?(ServerSocketChannel)?key??
  • ????????????????????????????.channel();??
  • ????????????????????//?獲得和客戶端連接的通道??
  • ????????????????????SocketChannel?channel?=?server.accept();??
  • ????????????????????//?設(shè)置成非阻塞??
  • ????????????????????channel.configureBlocking(false);??
  • ??
  • ????????????????????//在這里可以給客戶端發(fā)送信息哦??
  • ????????????????????channel.write(ByteBuffer.wrap(new?String("向客戶端發(fā)送了一條信息").getBytes()));??
  • ????????????????????//在和客戶端連接成功之后,為了可以接收到客戶端的信息,需要給通道設(shè)置讀的權(quán)限。??
  • ????????????????????channel.register(this.selector,?SelectionKey.OP_READ);??
  • ??????????????????????
  • ????????????????????//?獲得了可讀的事件??
  • ????????????????}?else?if?(key.isReadable())?{??
  • ????????????????????????read(key);??
  • ????????????????}??
  • ??
  • ????????????}??
  • ??
  • ????????}??
  • ????}??
  • ????/**?
  • ?????*?處理讀取客戶端發(fā)來(lái)的信息?的事件?
  • ?????*?@param?key?
  • ?????*?@throws?IOException??
  • ?????*/??
  • ????public?void?read(SelectionKey?key)?throws?IOException{??
  • ????????//?服務(wù)器可讀取消息:得到事件發(fā)生的Socket通道??
  • ????????SocketChannel?channel?=?(SocketChannel)?key.channel();??
  • ????????//?創(chuàng)建讀取的緩沖區(qū)??
  • ????????ByteBuffer?buffer?=?ByteBuffer.allocate(10);??
  • ????????channel.read(buffer);??
  • ????????byte[]?data?=?buffer.array();??
  • ????????String?msg?=?new?String(data).trim();??
  • ????????System.out.println("服務(wù)端收到信息:"+msg);??
  • ????????ByteBuffer?outBuffer?=?ByteBuffer.wrap(msg.getBytes());??
  • ????????channel.write(outBuffer);//?將消息回送給客戶端??
  • ????}??
  • ??????
  • ????/**?
  • ?????*?啟動(dòng)服務(wù)端測(cè)試?
  • ?????*?@throws?IOException??
  • ?????*/??
  • ????public?static?void?main(String[]?args)?throws?IOException?{??
  • ????????NIOServer?server?=?new?NIOServer();??
  • ????????server.initServer(8000);??
  • ????????server.listen();??
  • ????}??
  • ??
  • }??
  • ?

    ?

    客戶端:

    ?

    ?

    Java代碼??
  • package?cn.nio;??
  • ??
  • 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;??
  • ??
  • /**?
  • ?*?NIO客戶端?
  • ?*?@author?小路?
  • ?*/??
  • public?class?NIOClient?{??
  • ????//通道管理器??
  • ????private?Selector?selector;??
  • ??
  • ????/**?
  • ?????*?獲得一個(gè)Socket通道,并對(duì)該通道做一些初始化的工作?
  • ?????*?@param?ip?連接的服務(wù)器的ip?
  • ?????*?@param?port??連接的服務(wù)器的端口號(hào)??????????
  • ?????*?@throws?IOException?
  • ?????*/??
  • ????public?void?initClient(String?ip,int?port)?throws?IOException?{??
  • ????????//?獲得一個(gè)Socket通道??
  • ????????SocketChannel?channel?=?SocketChannel.open();??
  • ????????//?設(shè)置通道為非阻塞??
  • ????????channel.configureBlocking(false);??
  • ????????//?獲得一個(gè)通道管理器??
  • ????????this.selector?=?Selector.open();??
  • ??????????
  • ????????//?客戶端連接服務(wù)器,其實(shí)方法執(zhí)行并沒(méi)有實(shí)現(xiàn)連接,需要在listen()方法中調(diào)??
  • ????????//用channel.finishConnect();才能完成連接??
  • ????????channel.connect(new?InetSocketAddress(ip,port));??
  • ????????//將通道管理器和該通道綁定,并為該通道注冊(cè)SelectionKey.OP_CONNECT事件。??
  • ????????channel.register(selector,?SelectionKey.OP_CONNECT);??
  • ????}??
  • ??
  • ????/**?
  • ?????*?采用輪詢的方式監(jiān)聽(tīng)selector上是否有需要處理的事件,如果有,則進(jìn)行處理?
  • ?????*?@throws?IOException?
  • ?????*/??
  • ????@SuppressWarnings("unchecked")??
  • ????public?void?listen()?throws?IOException?{??
  • ????????//?輪詢?cè)L問(wèn)selector??
  • ????????while?(true)?{??
  • ????????????selector.select();??
  • ????????????//?獲得selector中選中的項(xiàng)的迭代器??
  • ????????????Iterator?ite?=?this.selector.selectedKeys().iterator();??
  • ????????????while?(ite.hasNext())?{??
  • ????????????????SelectionKey?key?=?(SelectionKey)?ite.next();??
  • ????????????????//?刪除已選的key,以防重復(fù)處理??
  • ????????????????ite.remove();??
  • ????????????????//?連接事件發(fā)生??
  • ????????????????if?(key.isConnectable())?{??
  • ????????????????????SocketChannel?channel?=?(SocketChannel)?key??
  • ????????????????????????????.channel();??
  • ????????????????????//?如果正在連接,則完成連接??
  • ????????????????????if(channel.isConnectionPending()){??
  • ????????????????????????channel.finishConnect();??
  • ??????????????????????????
  • ????????????????????}??
  • ????????????????????//?設(shè)置成非阻塞??
  • ????????????????????channel.configureBlocking(false);??
  • ??
  • ????????????????????//在這里可以給服務(wù)端發(fā)送信息哦??
  • ????????????????????channel.write(ByteBuffer.wrap(new?String("向服務(wù)端發(fā)送了一條信息").getBytes()));??
  • ????????????????????//在和服務(wù)端連接成功之后,為了可以接收到服務(wù)端的信息,需要給通道設(shè)置讀的權(quán)限。??
  • ????????????????????channel.register(this.selector,?SelectionKey.OP_READ);??
  • ??????????????????????
  • ????????????????????//?獲得了可讀的事件??
  • ????????????????}?else?if?(key.isReadable())?{??
  • ????????????????????????read(key);??
  • ????????????????}??
  • ??
  • ????????????}??
  • ??
  • ????????}??
  • ????}??
  • ????/**?
  • ?????*?處理讀取服務(wù)端發(fā)來(lái)的信息?的事件?
  • ?????*?@param?key?
  • ?????*?@throws?IOException??
  • ?????*/??
  • ????public?void?read(SelectionKey?key)?throws?IOException{??
  • ????????//和服務(wù)端的read方法一樣??
  • ????}??
  • ??????
  • ??????
  • ????/**?
  • ?????*?啟動(dòng)客戶端測(cè)試?
  • ?????*?@throws?IOException??
  • ?????*/??
  • ????public?static?void?main(String[]?args)?throws?IOException?{??
  • ????????NIOClient?client?=?new?NIOClient();??
  • ????????client.initClient("localhost",8000);??
  • ????????client.listen();??
  • ????}??
  • ??
  • }??
  • ?

    ?

    小結(jié):?

    終于把動(dòng)態(tài)代理和java NIO分析完了,呵呵,下面就要分析hadoop的RPC機(jī)制源碼了,博客地址:http://weixiaolu.iteye.com/blog/1504898?。不過(guò)如果對(duì)java NIO的理解存在異議的,歡迎一起討論。

    總結(jié)

    以上是生活随笔為你收集整理的Java NIO原理 图文分析及代码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

    主站蜘蛛池模板: 浓精h攵女乱爱av | 国产 日韩 欧美在线 | 国产白浆一区二区 | 国产日本一区二区三区 | 超级碰碰97 | 乌克兰做爰xxxⅹ性视频 | 日韩av在线播放不卡 | 日韩av一区二区三区 | 国产黄色免费视频 | 精品资源成人 | 波多野结衣加勒比 | 日本电影大尺度免费观看 | 理论片午午伦夜理片影院99 | 欧美精品久久久久久久久 | а√在线中文网新版地址在线 | 性生交大片免费看狂欲 | 久久大香焦 | 国产精品国产三级国产aⅴ下载 | www.日本精品 | 法国经典free性复古xxxx | 女人脱裤子让男人捅 | 日韩精品一二三四区 | 免费国产在线观看 | 久久99久久久久久 | 亚洲一区二区三区四区不卡 | 久久久精品视频网站 | 久青草视频在线观看 | 射影院 | 懂色av蜜臀av粉嫩av分享 | 精品一区二区三区视频在线观看 | 伊人国产在线视频 | 性欧美日韩 | 日韩中文在线观看 | 欧美日韩 一区二区三区 | 99欧美 | 亚洲色偷精品一区二区三区 | 奇米第四色7777 | 国产高清视频一区 | av在线免费播放网站 | a级成人毛片 | 四虎www| 老女人做爰全过程免费的视频 | 91精品久久久久 | 日本东京热一区二区 | 日韩三级一区二区三区 | 韩国性猛交╳xxx乱大交 | 超黄av| av网址有哪些| 色屋视频| jizz免费视频| 制服丝袜一区二区三区 | 国产成人免费在线 | 久久精品黄aa片一区二区三区 | 国产一区二区三区网站 | 精品成人 | 国产精品第二页 | 欧美日韩久久婷婷 | 日韩a√| 青春草久久 | 亚洲精品久久一区二区三区777 | 成人动漫av在线 | 尤物一区 | 亚洲欧美在线视频 | 久久久久精| 成年性生交大片免费看 | 久久久久久精 | 国产欧美日韩在线视频 | 成人91在线观看 | 亚洲爱v| 长篇高h肉爽文丝袜 | 国产乡下妇女做爰视频 | chinese麻豆新拍video | 亚洲精品久久久久avwww潮水 | 亚洲精品91天天久久人人 | 魔女鞋交玉足榨精调教 | 亚洲午夜福利一区二区三区 | 国产又爽又黄视频 | 春草 | 一个色综合久久 | 日韩性网站 | julia一区二区三区中文字幕 | 99re免费视频精品全部 | 日本电影一区二区三区 | 亚洲激情专区 | 黄色三级网 | 已满十八岁免费观看 | 美女脱光内衣内裤 | 欧美xxxxx少妇| 亚洲欧美一区二区在线观看 | 青青青国产视频 | 青青久操 | 日韩av在线看免费观看 | 欧美日韩一区免费 | 国产情侣自拍一区 | 日韩成人精品视频 | 成人免费视频免费观看 | 五十路黄色片 | 国产又粗又大又硬 | 国产欧美专区 |