NIO與BIO 介紹及經典程式碼
阿新 • • 發佈:2018-12-06
1 、NIO與BIO
IO為同步阻塞形式,NIO為同步非阻塞形式,NIO並沒有實現非同步,在JDK1.7後升級NIO庫包,支援非同步非阻塞
BIO:同步阻塞式IO,伺服器實現模式為一個連線一個執行緒,即客戶端有連線請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不做任何事情那麼就會造成不必要的執行緒開銷,當然可以通過執行緒池機制改善。
NIO:同步非阻塞式IO,伺服器實現模式為一個請求一個執行緒,即客戶端傳送的連線請求都會註冊到多路複用器上,多路複用器輪詢到連線有I/O請求時才啟動一個執行緒進行處理。
AIO(NIO.2):非同步非阻塞式IO,伺服器實現模式為一個有效請求一個執行緒,客戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動執行緒進行處理。
2、BIO NIO AIO區別
BIO: 同步 阻塞 的IO
NIO: 同步 非阻塞的IO(生產環境使用最多的一種IO)
AIO(nio2.0): 非同步 非阻塞IO
3、附帶NIO程式設計程式碼:NIO的服務端與客戶端
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; import java.util.Set; import java.lang.String; /** * NIO伺服器端 */ public class NioServer { public static void main(String[] args) { //建立緩衝區迎來儲存資料 ByteBuffer buffer = ByteBuffer.allocate(1024); try { //開啟伺服器通道 ServerSocketChannel scc = ServerSocketChannel.open(); //配置非阻塞伺服器端通道 scc.configureBlocking(false); //開啟選擇器 多路複用器 Selector selector = Selector.open(); //繫結一個埠 scc.bind(new InetSocketAddress(8899)); //在選擇器中註冊通道 scc.register(selector , SelectionKey.OP_ACCEPT); //迴圈挑選 while (true) { //阻塞 selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey sk = iterator.next(); //伺服器端通道的accept事件 if(sk.isAcceptable()) { SelectableChannel channel = sk.channel(); //把channel強轉成socketChannel事件 呼叫阻塞方法 SocketChannel accept = ((ServerSocketChannel) channel).accept(); //客戶端建立連線後立馬把客戶端的通道註冊到選擇器 accept.configureBlocking(false); accept.register(selector , SelectionKey.OP_READ); if(sk.isReadable()) { SocketChannel channel1 = (SocketChannel) sk.channel(); int len; //read方法在此處不阻塞 while ((len = channel1.read(buffer)) > 0) { buffer.flip(); byte [] b = new byte[buffer.limit()]; buffer.get(b); System.out.println(new String(b)); buffer.clear(); } if (len == -1) { System.out.println("讀到最後一個了吆"); channel1.close(); } } } } selectionKeys.clear(); } } catch (IOException e) { e.printStackTrace(); } } } **NIO客戶端** package NIOtest; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; /** * NIO客戶端 */ public class NioClient { public static void main(String[] args) throws IOException { SocketChannel s = SocketChannel.open(new InetSocketAddress("localhost",8899)); //jdk1.7以後支援false(同步非阻塞)通道 s.configureBlocking(false); ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put("HelloWorde".getBytes()); buffer.flip(); s.write(buffer); buffer.clear(); s.close(); } }
一點淺薄見解,如有錯誤或更好的理解,歡迎留言指出!