這篇文章主要介紹了Java 非阻塞I/O使用方法,文中涉及非阻塞I/O的簡介,同時向大家展示了利用非阻塞I/O實現客戶端的方法,需要的朋友可以參考下。
絕大部分知識與實例來自O'REILLY的《Java網絡程式設計》(Java Network Programming,Fourth Edition,by Elliotte Rusty Harold(O'REILLY))。
非阻塞I/O簡介
非阻塞I/O(NIO)是處理高並發的一種手段。在高並發的情況下,創建和回收線程以及在線程間切換的開銷變得不容忽視,此時就可以使用非阻塞I/O技術。這種技術的核心思想是每次選取一個準備好的連接,盡快填入這個連接所能管理的盡可能多的數據,然後轉向下一個準備好的連接。
利用非阻塞I/O實作的客戶端
#一般情況下,客戶端不會需要處理很高數量的並發連接。事實上,非阻塞I/O主要是為伺服器設計的,但它也可以用在客戶端。由於客戶端的設計相比伺服器容易,因此以下先用客戶端來進行簡單示範。
首先介紹通道(channel)和緩衝區。非阻塞I/O中使用SocketChannel類別建立連線。要取得SocketChannel對象,需要將SocketAddress物件(通常會使用它的子類別InetSocketAddress)傳入它的靜態工廠方法open()。下面為一個範例:
SocketAddress address = new InetSocketAddress("127.0.0.1", 19); SocketChannel client = SocketChannel.open(address);
open()方法是阻塞的,因此這之後的程式碼在連線建立之前不會執行。如果連線無法建立,會拋出一個IOException異常。
連接建立之後就需要取得輸入和輸出。有別於傳統的getInputStream()與getOutputStream(),利用頻道,你可以直接寫入頻道本身。不是寫入一個位元組數組,而是要寫入一個ByteBuffer物件。 ByteBuffer物件透過ByteBuffer.allocate(int capacity)取得,capacity為緩衝區大小,單位為位元組:
##
ByteBuffer buffer = ByteBuffer.allocate(74);取得ByteBuffer物件後,將其傳遞給SocketChannel物件的read()方法,SocketChannel物件會用從Socket讀取的資料填入這個緩衝區。 read()方法傳回成功讀取並儲存在緩衝區中的位元組數。預設情況下,它會至少讀取一個字節,或返回-1指示資料結束,沒有字節可用時阻塞。這與InputStream的行為大致相同。但如果設定成非阻塞模式,沒有位元組可用時它會立即回傳0,不會阻塞。
#
WritableByteChannel out = Channels.newChannel(System.out);上面的程式碼將System.out封裝入一個通道中。這之後就可以進行輸出了。 ByteBuffer物件在每次輸出之前,需要呼叫它的flip()方法,使得通道從開頭開始讀取。讀寫完畢後,還需要呼叫它的clear()方法,重置緩衝區的狀態。以下是進行一次資料輸出的程式碼:
buffer.flip(); out.write(buffer); buffer.clear();
實例1:利用非阻塞I/O實作的CharGenerator(字元產生器)用戶端
public static void createCharGeneratorServer(){ try(ServerSocket server = new ServerSocket(19)){ while(true){ try(Socket connection = server.accept()){ OutputStream out = connection.getOutputStream(); int firstPrintableCharacter = 33; int numberOfPrintableCharacter = 94; int numberOfCharactersPerLine = 72; int start = firstPrintableCharacter; while(true){ for(int i = start ; i < start + numberOfCharactersPerLine ; i++){ out.write (firstPrintableCharacter + (i - firstPrintableCharacter) % numberOfPrintableCharacter); } out.write('\r'); out.write('\n'); start = firstPrintableCharacter + (start + 1 - firstPrintableCharacter) % numberOfPrintableCharacter; } }catch (IOException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } }用戶端程式碼:
try { SocketAddress address = new InetSocketAddress("127.0.0.1", 19); SocketChannel client = SocketChannel.open(address); ByteBuffer buffer = ByteBuffer.allocate(74); WritableByteChannel out = Channels.newChannel(System.out); while(client.read(buffer) != -1){ buffer.flip(); out.write(buffer); buffer.clear(); } } catch (IOException e) { e.printStackTrace(); } 输出(无限循环): ]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEF ^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFG _`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGH `abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJ bcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK
啟用非阻塞模式
while(true){ //这里可以写每次循环都要做的事,无论有没有读到数据 int n = client.read(buffer); if(n > 0){ buffer.flip(); out.write(buffer); buffer.clear(); }else if (n == -1) { //除非服务器故障,否则不会发生 break; } }
總結
以上是Java中關於非阻塞I/O的使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Springboot項目多數據源配置下的數據庫訪問性能問題排查本文針對一個Springboot項目中使用Atomikos進行多數據源配�...

Java項目打包成可執行JAR文件時遭遇NoClassDefFoundError難題很多Java開發者在將項目打包成可執行JAR文件時,可能會�...

關於IntelliJIDEA破解的分析方法在編程界,IntelliJ...

問題介紹:視頻質量提升是視頻處理中的一個重要環節,尤其是在處理低清晰度的視頻時,如何利用Java語言和�...

在處理SpringBoot應用中,我們經常會遇到如何正確接收請求參數的問題。特別是當參數格式不是常見的JSON時,更�...

Java中聲明ConcurrentHashMap時加static的影響在Java編程中,ConcurrentHashMap...

自定義線程池中的initialize()方法的作用詳解當你在配置自定義線程池時,可能會注意到有一個initialize()方法。很...

關於曲線積分中變量代換的疑問提問者遇到一個曲線積分問題,其中一個步驟的計算結果令其困惑。題目給出了...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中