1. 程式人生 > >Netty之BIO(同步阻塞IO)、PIO(偽非同步阻塞IO)、NIO(非同步非阻塞IO)、AIO(非同步非阻塞IO)

Netty之BIO(同步阻塞IO)、PIO(偽非同步阻塞IO)、NIO(非同步非阻塞IO)、AIO(非同步非阻塞IO)

學習書籍:Netty權威指南

多種IO方式的比較:

1、BIO(同步阻塞IO)

使用ServerSocket繫結IP地址和監聽埠,客戶端發起連線,通過三次握手建立連線,用socket來進行通訊,通過輸入輸出流的方式來進行同步阻塞的通訊

每次客戶端發起連線請求,都會啟動一個執行緒

執行緒數量:客戶端併發訪問數為1:1,由於執行緒是Java虛擬機器中非常寶貴的資源,一旦執行緒數急劇增加,系統性能會急劇下降,導致執行緒棧溢位,建立新的執行緒失敗,並最終導致宕機

所以在JDK1.4之前,人們想到了一種方法,即PIO方式

2、PIO(偽非同步阻塞IO)

使用執行緒池來處理客戶端的請求

客戶端個數:執行緒池最大執行緒數=M:N,其中M遠大於N

在read和write的時候,還是IO阻塞的,只是把每個執行緒交由執行緒池來控制管理

3、NIO(非同步阻塞IO)

用NIO方式處理IO

使用多路複用器Selector來輪詢每個通道Channel,當通道中有事件時就通知處理,不會阻塞

使用相當複雜

伺服器實現模式為一個請求一個執行緒,客戶端傳送的連線請求都會註冊到多路複用器上,多路複用器輪詢到連線有I/O請求時才啟動一個執行緒進行處理。

4、AIO(真正的非同步非阻塞IO)

NIO2.0引入了新的非同步通道的概念,不需要使用多路複用器(Selector)對註冊通道進行輪詢即可實現非同步讀寫,從而簡化了NIO程式設計模型

使用Netty框架進行程式設計步驟

1、構建事件處理池

2、使用載入程式關聯事件處理池、通道、事件處理器

3、繫結埠服務

4、等待操作完成

5、關閉事件處理池

幾種IO的功能和特性對比


按照書上的例子碼了一遍:

服務端:

[java] view plain copy  print?
  1. import io.netty.bootstrap.ServerBootstrap;  
  2. import io.netty.channel.ChannelFuture;  
  3. import io.netty.channel.ChannelInitializer;  
  4. import io.netty.channel.ChannelOption;  
  5. import io.netty.channel.EventLoopGroup;  
  6. import io.netty.channel.nio.NioEventLoopGroup;  
  7. import io.netty.channel.socket.SocketChannel;  
  8. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  9. publicclass NettyServer {  
  10.     publicvoid bind(int port) throws Exception {  
  11.         EventLoopGroup bossGroup = new NioEventLoopGroup();  
  12.         EventLoopGroup workGroup = new NioEventLoopGroup();  
  13.         try {  
  14.             ServerBootstrap b = new ServerBootstrap();  
  15.             b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)  
  16.                     .option(ChannelOption.SO_BACKLOG, 1024)  
  17.                     .childHandler(new ChildChannelHandler());  
  18.             // 繫結埠,同步等待成功
  19.             ChannelFuture f = b.bind(port).sync();  
  20.             // 等待服務端監聽埠關閉
  21.             f.channel().closeFuture().sync();  
  22.         } catch (Exception e) {  
  23.             // TODO: handle exception
  24.         } finally {  
  25.             // 優雅退出,釋放執行緒池資源
  26.             bossGroup.shutdownGracefully();  
  27.             workGroup.shutdownGracefully();  
  28.         }  
  29.     }  
  30.     privateclass ChildChannelHandler extends ChannelInitializer<SocketChannel> {  
  31.         @Override
  32.         protectedvoid initChannel(SocketChannel ch) throws Exception {  
  33.             ch.pipeline().addLast(new NettyServerHandle());  
  34.         }  
  35.     }  
  36.     publicstaticvoid main(String[] args) throws Exception {  
  37.         int port = 8080;  
  38.         if (args != null && args.length > 0) {  
  39.             try {  
  40.                 port = Integer.valueOf(args[0]);  
  41.             } catch (Exception e) {  
  42.                 e.printStackTrace();  
  43.             }  
  44.         }  
  45.         new NettyServer().bind(port);  
  46.     }  
  47. }  
服務端處理器: [java] view plain copy  print?
  1. import io.netty.buffer.ByteBuf;  
  2. import io.netty.buffer.Unpooled;  
  3. import io.netty.channel.ChannelHandlerAdapter;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. publicclass NettyServerHandle extends ChannelHandlerAdapter {  
  6.     publicvoid channelRead(ChannelHandlerContext ctx, Object msg)  
  7.             throws Exception {  
  8.         ByteBuf buf = (ByteBuf) msg;  
  9.         byte[] req = newbyte[buf.readableBytes()];  
  10.         buf.readBytes(req);  
  11.         String body = new String(req, "UTF-8");  
  12.         System.out.println("The time server receive order:" + body);  
  13.         String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(  
  14.                 System.currentTimeMillis()).toString() : "BAD ORDER";  
  15.         ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());  
  16.         ctx.write(resp);  
  17.     }  
  18.     publicvoid channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
  19.         ctx.flush();  
  20.     }  
  21.     publicvoid exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
  22.         ctx.close();  
  23.     }  
  24. }  

客戶端: [java] view plain copy  print?
  1. import io.netty.bootstrap.Bootstrap;  
  2. import io.netty.channel.ChannelFuture;  
  3. import io.netty.channel.ChannelInitializer;  
  4. import io.netty.channel.ChannelOption;  
  5. import io.netty.channel.EventLoopGroup;  
  6. import io.netty.channel.nio.NioEventLoopGroup;  
  7. import io.netty.channel.socket.SocketChannel;  
  8. import io.netty.channel.socket.nio.NioSocketChannel;  
  9. publicclass NettyClient {  
  10.     publicvoid connect(int port, String host) throws Exception {  
  11.         // 1、建立執行緒池
  12.         EventLoopGroup group = new NioEventLoopGroup();  
  13.         try {  
  14.             // 2、使用引導器關聯執行緒池、通道、通達處理器、設定執行引數
  15.             Bootstrap b = new Bootstrap();  
  16.             b.group(group).channel(NioSocketChannel.class)  
  17.                     .option(ChannelOption.TCP_NODELAY, true)  
  18.                     .handler(new ChannelInitializer<SocketChannel>() {  
  19.                         @Override
  20.                         protectedvoid initChannel(SocketChannel ch)  
  21.                                 throws Exception {  
  22.                             ch.pipeline().addLast(new NettyClientHandle());  
  23.                         }  
  24.                     });  
  25.             // 發起非同步連線操作 3、繫結埠同步操作
  26.             ChannelFuture f = b.connect(host, port).sync();  
  27.             // 4、監聽埠關閉
  28.             f.channel().closeFuture().sync();  
  29.         } catch (Exception e) {  
  30.             // TODO: handle exception
  31.         } finally {  
  32.             // 優雅退出,釋放NIO執行緒組 5、釋放資源
  33.             group.shutdownGracefully();  
  34.         }  
  35.     }  
  36.     publicstaticvoid main(String[] args) throws Exception {  
  37.         int port = 8080;  
  38.         if (args != null && args.length > 0) {  
  39.             try {  
  40.                 port = Integer.valueOf(args[0]);  
  41.             } catch (Exception e) {  
  42.                 e.printStackTrace();  
  43.             }  
  44.         }  
  45.         new NettyClient().connect(port, "127.0.0.1");  
  46.     }  
  47. 相關推薦

    NettyBIO同步阻塞IOPIO非同步阻塞IONIO非同步阻塞IOAIO非同步阻塞IO

    學習書籍:Netty權威指南 多種IO方式的比較: 1、BIO(同步阻塞IO) 使用ServerSocket繫結IP地址和監聽埠,客戶端發起連線,通過三次握手建立連線,用socket來進行通訊,通過輸入輸出流的方式來進行同步阻塞的通訊 每次客戶端發起連線請求,都會

    NettyBIO同步阻塞IOPIO非同步阻塞IONIO非同步阻塞IOAIO非同步阻塞IONetty

    學習書籍:Netty權威指南 多種IO方式的比較: 1、BIO(同步阻塞IO) 使用ServerSocket繫結IP地址和監聽埠,客戶端發起連線,通過三次握手建立連線,用socket來進行通訊,通過輸入輸出流的方式來進行同步阻塞的通訊 每次客戶端發起連線請求,都會啟動一個執

    netty框架 基於noi的同步阻塞io長連線方案

    Socket通訊(BIO/NIO/AIO)程式設計         BIO:  傳統阻塞IO         NIO: 同步非阻塞式IO&nb

    Linux IO模型同步異步阻塞阻塞的幾篇好文章

    linux poll shu ppc pad tid per 多路復用 div 聊聊同步、異步、阻塞與非阻塞聊聊Linux 五種IO模型聊聊IO多路復用之select、poll、epoll詳解 ? Linux IO模型(同步異步阻塞非阻塞等)的幾篇好文章

    JDK5新特性線程同步工具類

    string 兩個人 exec random 主線程 一個人 exce print exchange 一. Semaphore Semaphore能夠控制同一時候訪問資源的線程個數, 比如: 實現一個文件同意的並發訪問數. Semaphore實現的功能就類似廁全部5個坑

    java並發線程同步synchronized和鎖機制

    blog 是否 can return nbsp jvm 環境 imp ava 使用synchronized實現同步方法 使用非依賴屬性實現同步 在同步塊中使用條件(wait(),notify(),notifyAll()) 使用鎖實現同步 使用讀寫鎖實現同步數據訪問 修改

    python並發編程多進程(二):互斥鎖同步&進程其他屬性&進程間通信queue&生產者消費者模型

    互斥 數據 socket pan copy src too 如果 搶票 一,互斥鎖,同步鎖 進程之間數據不共享,但是共享同一套文件系統,所以訪問同一個文件,或同一個打印終端,是沒有問題的, 競爭帶來的結果就是錯亂,如何控制,就是加鎖處理 part1:多個進程共享同

    Python進程同步控制鎖信號量事件 進程間通信——隊列和管道

    load 很快 容器 數據安全 全部 傳遞 幫我 之前 引入 進程同步(multiprocess.Lock、multiprocess.Semaphore、multiprocess.Event) 鎖 —— multiprocess.Lock 通過剛剛的學習,我們千方百計實現了

    python筆記10-多線程線程同步鎖lock

    pre 創建 函數 必須 col threading code png sta 前言 關於吃火鍋的場景,小夥伴並不陌生,吃火鍋的時候a同學往鍋裏下魚丸,b同學同時去吃掉魚丸,有可能會導致吃到生的魚丸。為了避免這種情況,在下魚丸的過程中,先鎖定操作,讓吃火鍋的小夥伴停一會,等

    Node學習基礎(三) 檔案的同步非同步寫入操作fs_檔案系統

    下面遇到看不懂的可以去看官方文件。 首先引入fs模組 第二步開啟檔案  官方文件格式是這樣  path 檔案路徑  這裡例子裡是FileHello.txt  如果沒有這個檔案 所以他會自動建立 FileHello.txt

    Boost.Interprocess使用手冊翻譯六:同步機制Synchronization mechanisms

    六.          同步機制 同步機制概述 互斥量 條件變數 訊號量 升級互斥量 通過移動語義轉移鎖 檔案鎖 訊息佇列   同步

    OpenCV3——畫時鐘同步本地時間

    本文是看了網上一個部落格的例項,覺得很好玩,複製程式碼,做了一些修改,調通了之後,做的一些分享。參考原文為:http://blog.csdn.net/xingchenbingbuyu/article/details/50762351 主要修改的地方:1、獲取系統時間  2、

    Java 網路IO程式設計總結BIONIOAIO均含完整例項程式碼

    第一段內容轉載自:http://blog.51cto.com/stevex/1284437 先來個例子理解一下概念,以銀行取款為例: 同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時,Java自己處理IO讀寫)。 非同步

    西南民族大學第十屆校賽同步(J題——怪盜基德 & 月瞳寶石)

    題目描述 在這片寂靜的夜色之下,他就這樣靜靜的降臨在我的面前,他的眼神就好像能看透了一切,露出了無所畏懼的笑容。一襲白斗篷和一頂白禮帽,不帶一絲多餘的動作,他的臉在單眼眼睛跟逆光之下。 to 世紀末的魔術師 By the mysterious man 怪盜基德在上次失敗後,對美麗

    NIO程式設計同步阻塞同步阻塞詳解

    NIO同步阻塞與同步非阻塞 BIO與NIO IO為同步阻塞形式,NIO為同步非阻塞形式,NIO並沒有實現非同步,在JDK1.7後升級NIO庫包,支援非同步非阻塞 同學模型NIO2.0(AIO) BIO(同步阻塞式IO) 同步阻塞式IO

    Netty心跳檢測可應用在分散式架構

            這次繼續上一篇說到的心跳檢測          我們使用Socket通訊一般經常會處理多個伺服器之間的心跳檢測,一般來講我們去維護伺服器叢集,肯定要有一臺或者N臺伺服器主機(Master),然後還應該有N臺(Slave),那麼我們的主機肯定要時時刻刻知道自己

    Netty實現自定義簡單的編解碼器一MessageToByteEncoder和ByteToMessageDecoder

    1、關於自定義編碼器的簡介       在這裡實現的編解碼器很簡單。編碼器的功能實現的是,int--->byets的編碼;解碼器實現的是,bytes--->int的解碼。 2、編碼器的實現 import io.netty.buffer.ByteBuf; imp

    Netty netty原始碼學習netty server端原始碼初讀

    上一篇簡單的分析了一下NioEventLoop,ServerBootstrap等元件的建立過程做的一些操作 現在我們一起看下當SingleThreadEventExecutor.java中的thread啟動後,netty做的一些最最重要的一些操作 我們接著昨天的程

    從零開始學習音視訊程式設計技術FFMPEG Qt視訊播放器音視訊同步

    前面分別講解了: 現在我們就將視訊和音訊合併,並讓聲音和畫面同步。 加入音訊的部分就不做講解了,這裡主要講下聲音和視訊同步的步驟。 首先剛開始播放的時候通過av_gettime()獲取系統主時鐘,記錄下來。 以後便不斷呼叫av_gettime()獲取系統時鐘

    多執行緒執行緒互動互斥與同步

    首先我們通過一個有意思的案例來引入由於執行緒爭用條件造成的一些嚴重的問題。 下面的程式碼簡單來說是初始化多個能量盒子,每個盒子所含初始能量相同,這樣總能量就固定了。開設多個執行緒將這些盒子的能量相互轉移,在轉移過程就出現了問題。 package disappearEner