您好,登錄后才能下訂單哦!
NIO是什么
New IO,始于Java1.4,提供新的非阻塞 JavaIO 操作API.
又稱Non-Blocking IO 非阻塞IO
替代舊版本的Blocking IO, 多用于網絡相關的API.
為什么要使用NIO
使用NIO后,WEB網絡程序性能可以進一步提高
模擬Tomcat7, 阻塞IO處理Http請求:
public class BIOHttpServer {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(8080);
System.out.println(Thread.currentThread().getName()+"啟動:"+8080);
while(true){
Socket accept = socket.accept();
InputStream inputStream = accept.getInputStream();
byte[] b = new byte[1024];
inputStream.read(b);
System.out.println(new String(b));
// http響應頭 必須這樣寫:
String response = "HTTP/1.1 200 ok\r\nContent-Length: 11\r\n\r\nHello World\r\n";
accept.getOutputStream().write(response.getBytes());
accept.getOutputStream().flush();
accept.close();
}
}
}
NIO高性能的核心原理:
發起連接
操作系統接收連接
TCP模塊 + 多路復用機制
一個Java線程通過Selector工具選擇性處理
有數據傳輸的交給線程池
最終達到,線程最大程度利用
使用NIO:
模擬Tomcat8.5, NIO處理Http請求:
public class NIOHttpServer {
public static void main(String[] args) throws IOException {
// 1.ServerSocketChannel 綁定端口
ServerSocketChannel socket = ServerSocketChannel.open();
socket.configureBlocking(false); // no-Blocking
socket.bind(new InetSocketAddress(8080));
System.out.println("NIO服務器啟動,端口:"+8080);
// 2.獲取新連接
// selector 獲取不同操作系統下不同的tcp連接動態
Selector selector = Selector.open();
// 選擇器,根據條件查詢符合情況地TCP連接
socket.register(selector, SelectionKey.OP_ACCEPT);
while(true){
selector.select(1000); //如果沒有新連接,就等待
// 3. 處理查詢結果
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while(iterator.hasNext()){
SelectionKey result = iterator.next();
//根據不同的類型,分別進行處理
if(result.isAcceptable()){ //3.1 拿到新連接對象
// nio體現,accept 不阻塞,沒有連接則返回null
SocketChannel accept = socket.accept();
if(accept!=null){
// 注冊連接對象,進行關注
accept.configureBlocking(false);// no-Blocking
accept.register(selector, SelectionKey.OP_READ);
}
}
if(result.isReadable()){ //3.2 有數據請求的連接
SocketChannel channel = (SocketChannel) result.channel();
// 處理過程中,先取消selector對應連接的注冊,避免重復
result.cancel();
// NIO的讀寫方式: 字節緩沖區
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
channel.read(byteBuffer);
byteBuffer.flip(); //模式轉換
byte[] b = byteBuffer.array();
String request = new String(b);
//處理請求...
System.out.println(request);
//數據響應:NIO的寫數據
String response = "HTTP/1.1 200 ok\r\nContent-Length: 11\r\n\r\nHello World\r\n";
channel.write(ByteBuffer.wrap(response.getBytes()));
// 處理完成,重新注冊,繼續接收處理新的連接
// channel.register(selector, SelectionKey.OP_READ);
}
// 刪除處理過的結果(事件)
iterator.remove();
}
// 檢查過程就緒,清除之前的調用效果
selector.selectNow();
}
}
}
(本文章由源碼時代技術老師原創,轉載請注明出處!)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。