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