NIO模式主要優勢是展現在對多連接配接的管理,對衆多連接配接各種事件的轉發讓處理變得更加高效,是以一般是伺服器端才會使用NIO模式,而對于用戶端為了友善及習慣使用阻塞模式的Socket進行通信。是以NIO模式的例子也僅僅看下服務端的實作即可。
public class NioServer {
private ByteBuffer readBuffer;
private Selector selector;
private void init() {
readBuffer = ByteBuffer.allocate(1024);
ServerSocketChannel servSocketChannel;
try {
servSocketChannel = ServerSocketChannel.open();
servSocketChannel.configureBlocking(false);
servSocketChannel.socket().bind(new InetSocketAddress(8888));
selector = Selector.open();
servSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
}
private void listen() {
while (true) {
selector.select();
Iterator ite = selector.selectedKeys().iterator();
while (ite.hasNext()) {
SelectionKey key = (SelectionKey) ite.next();
ite.remove();
handleKey(key);
} catch (Throwable t) {
t.printStackTrace();
private void handleKey(SelectionKey key) throws IOException,ClosedChannelException {
SocketChannel channel = null;
if (key.isAcceptable()) {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
channel = serverChannel.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
channel = (SocketChannel) key.channel();
readBuffer.clear();
int count = channel.read(readBuffer);
if (count > 0) {
readBuffer.flip();
ByteBuffer response = ByteBuffer.wrap(new byte[] { 'r','e', 's', 'p', 'o', 'n', 's', 'e' });
byte[] request=new byte[7];
System.out.println(readBuffer.get(request));
while (response.hasRemaining()) {
channel.write(response);
} else {
channel.close();
if (channel != null) {
public static void main(String[] args) {
NioServer nioServer = new NioServer();
nioServer.init();
nioServer.listen();
初始化方法主要做的事情包括配置設定讀緩沖、開啟一個ServerSocketChannel通道并設定為非阻塞、綁定8888端口、開啟一個選擇器Selector、将ServerSocketChannel對象以OP_ACCEPT作為感興趣事件注冊到選擇器中。
監聽方法主要做的事情是不斷通過選擇器select出感興趣的事件,再将對應的key送到handleKey方法處理,分三種事件說明,①OP_ACCEPT事件,一個用戶端連接配接連進來最開始會觸發一個接收事件,此時要通過調用ServerSocketChannel對象的accept将用戶端連接配接接收,并将接收到的用戶端channel設定為非阻塞,最後将用戶端channel以OP_READ事件注冊到選擇器中;②OP_READ事件,假如用戶端連接配接寫入“request”字元串,服務端選擇器選擇出該通道有字元串待讀,從key中擷取對應channel并執行read操作,這裡會輸出“request”字元串,然後向用戶端輸出“response”字元串;③OP_WRITE事件,這裡為友善并沒有注冊寫事件而是直接将位元組串寫回用戶端,實際進行中可以這樣:先嘗試直接往通道寫入,在網絡阻塞時即循環寫入資料寫不了時則注冊OP_WRITE事件避免線程阻塞,交給後面選擇器select後再次進行寫處理。
非阻塞模式提供了另外一種IO處理模型,把阻塞操作改成非阻塞操作,增加了程式編寫的難度,但如果要寫出高性能高并發的服務端服務則必須掌握NIO模式。
========廣告時間========鄙人的新書《Tomcat核心設計剖析》已經在京東銷售了,有需要的朋友可以到 https://item.jd.com/12185360.html 進行預定。感謝各位朋友。[為什麼寫《Tomcat核心設計剖析》](http://blog.csdn.net/wangyangzhizhou/article/details/74080321)=========================歡迎關注:![這裡寫圖檔描述](http://img.blog.csdn.net/20170509102539658?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3lhbmd6aGl6aG91/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)