1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務時間:8:30-17:00
      你可能遇到了下面的問題
      關閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      netty系列之JavaBIONIOAIO進化史-創(chuàng)新互聯(lián)

      簡介

      上一章我們介紹了IO的五種模型,實際上Java只支持其中的三種,即BIO/NIO/AIO。

      創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設計制作、成都網(wǎng)站制作與策劃設計,古田網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設十余年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:古田等地區(qū)。古田做網(wǎng)站價格咨詢:18980820575

      本文將介紹Java中這三種IO的進化史,并從使用的角度剖析它們背后的故事。

      Java BIO

      BIO概念解析

      BIO,Blocking IO,阻塞IO,它是Java的上古產(chǎn)品,自出生就有的東西(JDK 1.0)。

      使用BIO則數(shù)據(jù)準備和數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間兩個階段都是阻塞的。

      netty系列之Java BIO NIO AIO進化史

      BIO使用案例

      public?class?EchoServer?{????public?static?void?main(String[]?args)?throws?IOException?{
      ????????ServerSocket?serverSocket?=?new?ServerSocket(8080);????????while?(true)?{
      ????????????System.out.println("start?accept");
      ????????????Socket?socket?=?serverSocket.accept();
      ????????????System.out.println("new?conn:?"?+?socket.getRemoteSocketAddress());????????????new?Thread(()->{????????????????try?{
      ????????????????????BufferedReader?reader?=?new?BufferedReader(new?InputStreamReader(socket.getInputStream()));
      ????????????????????String?msg;????????????????????//?讀取消息,本文來源公從號彤哥讀源碼
      ????????????????????while?((msg?=?reader.readLine())?!=?null)?{????????????????????????if?(msg.equalsIgnoreCase("quit"))?{
      ????????????????????????????reader.close();
      ????????????????????????????socket.close();????????????????????????????break;
      ????????????????????????}?else?{
      ????????????????????????????System.out.println("receive?msg:?"?+?msg);
      ????????????????????????}
      ????????????????????}
      ????????????????}?catch?(IOException?e)?{
      ????????????????????e.printStackTrace();
      ????????????????}
      ????????????}).start();
      ????????}
      ????}
      }

      客戶端可以使用telnet來測試,而且你可以使用多個telnet來測試:

      [c:\~]$?telnet?127.0.0.1?8080Connecting?to?127.0.0.1:8080...
      Connection?established.
      To?escape?to?local?shell,?press?'Ctrl+Alt+]'.
      hello?world
      我是人才
      quit
      Connection?closed?by?foreign?host.

      BIO的使用方式非常簡單,服務端接收到一個連接就啟動一個線程來處理這個連接的所有請求。

      netty系列之Java BIO NIO AIO進化史

      所以,BIO大的缺點就是浪費資源,只能處理少量的連接,線程數(shù)隨著連接數(shù)線性增加,連接越多線程越多,直到抗不住。

      Java NIO

      NIO概念解析

      NIO,New IO,JDK1.4開始支持,內(nèi)部是基于多路復用的IO模型。

      netty系列之Java BIO NIO AIO進化史

      這里有個歧義,很多人認為Java的NIO是Non-Blocking IO的縮寫,其實并不是。

      使用NIO則多條連接的數(shù)據(jù)準備階段會阻塞在select上,數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間依然是阻塞的。

      因為第一階段并不是連接本身處于阻塞階段,所以通常來說NIO也可以看作是同步非阻塞IO。

      NIO使用案例

      public?class?EchoServer?{????public?static?void?main(String[]?args)?throws?IOException?{
      ????????Selector?selector?=?Selector.open();
      ????????ServerSocketChannel?serverSocketChannel?=?ServerSocketChannel.open();
      ????????serverSocketChannel.bind(new?InetSocketAddress(8080));
      ????????serverSocketChannel.configureBlocking(false);????????//?將accept事件綁定到selector上
      ????????serverSocketChannel.register(selector,?SelectionKey.OP_ACCEPT);????????while?(true)?{????????????//?阻塞在select上
      ????????????selector.select();
      ????????????Set?selectionKeys?=?selector.selectedKeys();????????????//?遍歷selectKeys
      ????????????Iterator?iterator?=?selectionKeys.iterator();????????????while?(iterator.hasNext())?{
      ????????????????SelectionKey?selectionKey?=?iterator.next();????????????????//?如果是accept事件
      ????????????????if?(selectionKey.isAcceptable())?{
      ????????????????????ServerSocketChannel?ssc?=?(ServerSocketChannel)?selectionKey.channel();
      ????????????????????SocketChannel?socketChannel?=?ssc.accept();
      ????????????????????System.out.println("accept?new?conn:?"?+?socketChannel.getRemoteAddress());
      ????????????????????socketChannel.configureBlocking(false);
      ????????????????????socketChannel.register(selector,?SelectionKey.OP_READ);
      ????????????????}?else?if?(selectionKey.isReadable())?{????????????????????//?如果是讀取事件,本文來源公從號彤哥讀源碼
      ????????????????????SocketChannel?socketChannel?=?(SocketChannel)?selectionKey.channel();
      ????????????????????ByteBuffer?buffer?=?ByteBuffer.allocate(1024);????????????????????//?將數(shù)據(jù)讀入到buffer中
      ????????????????????int?length?=?socketChannel.read(buffer);????????????????????if?(length?>?0)?{
      ????????????????????????buffer.flip();????????????????????????byte[]?bytes?=?new?byte[buffer.remaining()];????????????????????????//?將數(shù)據(jù)讀入到byte數(shù)組中
      ????????????????????????buffer.get(bytes);????????????????????????//?換行符會跟著消息一起傳過來
      ????????????????????????String?content?=?new?String(bytes,?"UTF-8").replace("\r\n",?"");????????????????????????if?(content.equalsIgnoreCase("quit"))?{
      ????????????????????????????selectionKey.cancel();
      ????????????????????????????socketChannel.close();
      ????????????????????????}?else?{
      ????????????????????????????System.out.println("receive?msg:?"?+?content);
      ????????????????????????}
      ????????????????????}
      ????????????????}
      ????????????????iterator.remove();
      ????????????}
      ????????}
      ????}
      }

      這里同樣使用telnet測試,而且你可以使用多個telnet來測試:

      [c:\~]$?telnet?127.0.0.1?8080Connecting?to?127.0.0.1:8080...
      Connection?established.
      To?escape?to?local?shell,?press?'Ctrl+Alt+]'.
      hello?world
      我是人才
      quit
      Connection?closed?by?foreign?host.

      NIO的使用方式就有點復雜了,但是一個線程就可以處理很多連接。

      首先,需要注冊一個ServerSocketChannel并把它注冊到selector上并監(jiān)聽accept事件,然后accept到連接后會獲取到SocketChannel,同樣把SocketChannel也注冊到selector上,但是監(jiān)聽的是read事件。焦作國醫(yī)胃腸醫(yī)院靠譜嗎_正規(guī)胃腸專科醫(yī)院:http://jz.lieju.com/zhuankeyiyuan/37570896.htm

      netty系列之Java BIO NIO AIO進化史

      NIO大的優(yōu)點,就是一個線程就可以處理大量的連接,缺點是不適合處理阻塞性任務,因為阻塞性任務會把這個線程占有著,其它連接的請求將得不到及時處理。

      Java AIO

      AIO概念介紹

      AIO,Asynchronous IO,異步IO,JDK1.7開始支持,算是一種比較完美的IO,Windows下比較成熟,但Linux下還不太成熟。

      netty系列之Java BIO NIO AIO進化史

      使用異步IO則會在請求時立即返回,并在數(shù)據(jù)已準備且已拷貝到用戶空間后進行回調(diào)處理,兩個階段都不會阻塞。

      AIO使用案例

      public?class?EchoServer?{????public?static?void?main(String[]?args)?throws?IOException?{
      ????????AsynchronousServerSocketChannel?serverSocketChannel?=?AsynchronousServerSocketChannel.open();
      ????????serverSocketChannel.bind(new?InetSocketAddress(8080));????????//?監(jiān)聽accept事件,本文來源公從號彤哥讀源碼
      ????????serverSocketChannel.accept(null,?new?CompletionHandler()?{????????????@Override
      ????????????public?void?completed(AsynchronousSocketChannel?socketChannel,?Object?attachment)?{????????????????try?{
      ????????????????????System.out.println("accept?new?conn:?"?+?socketChannel.getRemoteAddress());????????????????????//?再次監(jiān)聽accept事件
      ????????????????????serverSocketChannel.accept(null,?this);????????????????????//?消息的處理
      ????????????????????while?(true)?{
      ????????????????????????ByteBuffer?buffer?=?ByteBuffer.allocate(1024);????????????????????????//?將數(shù)據(jù)讀入到buffer中
      ????????????????????????Future?future?=?socketChannel.read(buffer);????????????????????????if?(future.get()?>?0)?{
      ????????????????????????????buffer.flip();????????????????????????????byte[]?bytes?=?new?byte[buffer.remaining()];????????????????????????????//?將數(shù)據(jù)讀入到byte數(shù)組中
      ????????????????????????????buffer.get(bytes);
      
      ????????????????????????????String?content?=?new?String(bytes,?"UTF-8");????????????????????????????//?換行符會當成另一條消息傳過來
      ????????????????????????????if?(content.equals("\r\n"))?{????????????????????????????????continue;
      ????????????????????????????}????????????????????????????if?(content.equalsIgnoreCase("quit"))?{
      ????????????????????????????????socketChannel.close();????????????????????????????????break;
      ????????????????????????????}?else?{
      ????????????????????????????????System.out.println("receive?msg:?"?+?content);
      ????????????????????????????}
      ????????????????????????}
      ????????????????????}
      ????????????????}?catch?(Exception?e)?{
      ????????????????????e.printStackTrace();
      ????????????????}
      ????????????}????????????@Override
      ????????????public?void?failed(Throwable?exc,?Object?attachment)?{
      ????????????????System.out.println("failed");
      ????????????}
      ????????});????????//?阻塞住主線程
      ????????System.in.read();
      ????}
      }

      這里同樣使用telnet測試,而且你可以使用多個telnet來測試:

      [c:\~]$?telnet?127.0.0.1?8080Connecting?to?127.0.0.1:8080...
      Connection?established.
      To?escape?to?local?shell,?press?'Ctrl+Alt+]'.
      hello?world
      我是人才
      quit
      Connection?closed?by?foreign?host.

      AIO的使用方式不算太復雜,默認會啟一組線程來處理用戶的請求,而且如果在處理阻塞性任務,還會自動增加新的線程來處理其它連接的任務。

      首先,創(chuàng)建一個AsynchronousServerSocketChannel并調(diào)用其accept方法,這一步相當于監(jiān)聽了accept事件,在收到accept事件后會獲取到AsynchronousSocketChannel,然后就可以在回調(diào)方法completed()里面讀取數(shù)據(jù)了,當然也要繼續(xù)監(jiān)聽accept事件。

      AIO大的優(yōu)點,就是少量的線程就可以處理大量的連接,而且可以處理阻塞性任務,但不能大量阻塞,否則線程數(shù)量會膨脹。

      槽點

      (1)三種IO的實現(xiàn)方式中對于換行符的處理竟然都不一樣,BIO中不會把換行符帶過來(其實是帶過來了,因為用了readLine()方法,所以換行符沒了),NIO中會把換行符加在消息末尾,AIO中會把換行符當成一條新的消息傳過來,很神奇,為啥不統(tǒng)一處理呢,也很疑惑。焦作國醫(yī)胃腸醫(yī)院地址__大愛國醫(yī):http://jz.lieju.com/zhuankeyiyuan/37570264.htm

      (2)JDK自帶的ByteBuffer是一個難用的東西。

      總結(jié)

      本文我們從概念和使用兩個角度分別介紹了BIO/NIO/AIO三種IO模型。

      問題

      看起來JDK的實現(xiàn)似乎很完美啊,為什么還會有Netty呢?

      最后,也歡迎來我的公從號彤哥讀源碼系統(tǒng)地學習源碼&架構的知識。

      創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡助力業(yè)務部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準確進行流量調(diào)度,確保服務器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務器買多久送多久。


      分享題目:netty系列之JavaBIONIOAIO進化史-創(chuàng)新互聯(lián)
      當前網(wǎng)址:http://www.ef60e0e.cn/article/dhjshe.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        广水市| 汾阳市| 泉州市| 加查县| 南涧| 星子县| 珲春市| 宁津县| 集安市| 玉龙| 石嘴山市| 陕西省| 平湖市| 黄骅市| 吴桥县| 桃江县| 衡阳县| 社旗县| 义乌市| 三门峡市| 岳池县| 鹿泉市| 阿克| 赫章县| 南澳县| 柳林县| 颍上县| 读书| 拜城县| 长沙县| 嘉善县| 贵南县| 从化市| 兴安县| 鄄城县| 贵阳市| 五华县| 墨脱县| 鄱阳县| 常熟市| 商都县|