您好,登錄后才能下訂單哦!
這篇文章主要介紹“Netty NIO的簡單介紹”,在日常操作中,相信很多人在Netty NIO的簡單介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Netty NIO的簡單介紹”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
也就是傳統IO(也就是InputStream、OutputStream等Java中IO包下的類以及 java.net下面提供的部分網絡 API,比如 Socket、ServerSocket、HttpURLConnection 也歸類到同步阻塞 IO 類庫,因為網絡通信同樣是 IO 行為。)在進行讀寫操作(調用read/write方法)時會停止當前線程,使得當前線程進入阻塞狀態,直到讀寫操作結束后,線程才能繼續執行。
傳統IO的同步阻塞問題導致了其在性能上的極大缺陷,因為每一個線程在同一時刻只能管理(運行)一個IO流,尤其是對于網絡應用程序來說,如果采用傳統IO方式,那么只能一個線程管理持有一個IO流,這對于系統來說并發情況下的性能瓶頸就太大了,代碼如下所示
import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 傳統socket服務端 * */ public class ioServer { @SuppressWarnings("resource") public static void main(String[] args) throws Exception { ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); //創建socket服務,監聽10101端口 ServerSocket server=new ServerSocket(10101); System.out.println("服務器啟動!"); while(true){ //獲取一個套接字(阻塞) final Socket socket = server.accept(); System.out.println("來個一個新客戶端!"); newCachedThreadPool.execute(new Runnable() { @Override public void run() { //業務處理 handler(socket); } }); } } /** * 讀取數據 * @param socket * @throws Exception */ public static void handler(Socket socket){ try { byte[] bytes = new byte[1024]; InputStream inputStream = socket.getInputStream(); while(true){ //讀取數據(阻塞) int read = inputStream.read(bytes); if(read != -1){ System.out.println(new String(bytes, 0, read)); }else{ break; } } } catch (Exception e) { e.printStackTrace(); }finally{ try { System.out.println("socket關閉"); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
如果使用傳統IO方式,那么就必須為每一個連接到服務端的客戶端建立一個線程來處理IO,并發量低的時候還好,可是一旦并發量極高,造成創建大量線程,就會導致非常頻繁的進行線程間切換,這對系統性能消耗極大,而且線程切換是無用的消耗。
同步和阻塞是有區別的,它們的修飾對象是不同的。
阻塞和非阻塞是指進程訪問的數據如果尚未就緒,進程是否需要等待,簡單說這相當于函數內部的實現區別,也就是未就緒時是直接返回還是等待就緒。
同步和異步是指訪問數據的機制,同步一般指主動請求并等待I/O操作完畢的方式,當數據就緒后在讀寫的時候必須阻塞,異步則指主動請求數據后便可以繼續處理其它任務,隨后等待I/O,操作完畢的通知,這可以使進程在數據讀寫時也不阻塞。
為了改善傳統IO的問題,在 Java 1.4 中引入了 NIO 框架(java.nio 包),提供了 Channel、Selector、Buffer 等新的類,可以構建多路復用的、同步非阻塞 IO 程序,同時提供了更接近操作系統底層的高性能數據操作方式。在 Java 7 中,NIO 有了進一步的改進,也就是 NIO 2,引入了異步非阻塞 IO 方式,也有很多人叫它 AIO(Asynchronous IO)。異步 IO 操作基于事件和回調機制,可以簡單理解為,讀寫操作直接返回,而不會阻塞在那里,當后臺處理完成,操作系統會通知相應線程進行后續工作,并發性能再次提升。針對
Java中為NIO提供三個核心實現類,主要是緩沖區(Buffer)、通道(Channel)、選擇器(Selector)。
1. 通道(Channel):原本在傳統IO中是通過流來進行讀寫操作,但是在NIO中是采用Channel來進行讀寫操作,Channel替代了傳統IO中的流。
2. Java中提供了Channel的幾種具體實現類,這些通道涵蓋了UDP 和 TCP 網絡IO,以及文件IO。
FileChannel:文件IO
DatagramChannel:UDP網絡IO
SocketChannel:TCP客戶端網絡IO
ServerSocketChannel:TCP服務端網絡IO
3. Channel有三個特點:
Channel是可讀可寫的,但是一個Channel要么只能寫要么只能讀
Channel可以異步的讀和寫
數據總是從Channel中讀到Buffer,或者從Buffer中寫到Channel
1. Channel負責讀寫數據,而緩沖區Buffer則負責臨時保存Channel讀寫的數據,也就是緩存數據,所有的數據都會經過Buffer寫入到Channel或者從Channel中讀取存儲到Buffer。JavaNIO中為Buffer提供了所有基本數據類型的實現類,覆蓋了你能通過IO發送的基本數據類型:byte, short, int, long, float, double 和 char。還有另外一個MappedByteBuffer。
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
1. 傳統IO因為一個線程對應一個IO的局限導致其在高并發下的性能浪費,而NIO中則因為Selector的存在實現了允許一個單獨的線程來監視多個輸入通道,你可以注冊多個通道使用一個選擇器,然后使用一個單獨的線程來“選擇”通道:這些通道里已經有可以處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。
要使用Selector,得向Selector注冊Channel,然后調用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件,事件的例子有如新連接進來,數據接收等。
到此,關于“Netty NIO的簡單介紹”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。