摘要:會關聯線程池,它的任務是接收處理事件,并分發給負責處理通道中操作結果的結果處理器。跟通道中發起的操作關聯的結果處理器確保是由線程池中的某個線程產生。基本思想是主線程會派一個偵查員到獨立的線程中執行操作。
簡介
jdk7中新增了一些與文件(網絡)I/O相關的一些api。這些API被稱為NIO.2,或稱為AIO(Asynchronous I/O)。AIO最大的一個特性就是異步能力,這種能力對socket與文件I/O都起作用。AIO其實是一種在讀寫操作結束之前允許進行其他操作的I/O處理。AIO是對JDK1.4中提出的同步非阻塞I/O(NIO)的進一步增強。
關于NIO,之前的一篇文章可以看看:java中的NIO
jdk7主要增加了三個新的異步通道:
AsynchronousFileChannel: 用于文件異步讀寫;
AsynchronousSocketChannel: 客戶端異步socket;
AsynchronousServerSocketChannel: 服務器異步socket。
因為AIO的實施需充分調用OS參與,IO需要操作系統支持、并發也同樣需要操作系統的支持,所以性能方面不同操作系統差異會比較明顯。
前提概念在具體看AIO之前,我們需要知道一些必要的前提概念。
Unix中的I/O模型Unix定義了五種I/O模型
阻塞I/O
非阻塞I/O
I/O復用(select、poll、linux 2.6種改進的epoll)
信號驅動IO(SIGIO)
異步I/O(POSIX的aio_系列函數)
一個戲謔的例子:
如果你想吃一份宮保雞丁蓋飯:
同步阻塞:你到飯館點餐,然后在那等著,還要一邊喊:好了沒啊!
同步非阻塞:在飯館點完餐,就去遛狗了。不過溜一會兒,就回飯館喊一聲:好了沒啊!
異步阻塞:遛狗的時候,接到飯館電話,說飯做好了,讓您親自去拿。
異步非阻塞:飯館打電話說,我們知道您的位置,一會給你送過來,安心遛狗就可以了。
詳情參見文章末尾的他山之石-Unix下五種IO模型。
Reactor與Proactor兩種IO多路復用方案:Reactor and Proactor。
Reactor模式是基于同步I/O的,而Proactor模式是和異步I/O相關的。
reactor:能收了你跟俺說一聲。proactor: 你給我收十個字節,收好了跟俺說一聲。
詳情參見文章末尾的他山之石-IO設計模式:Reactor和Proactor對比。
異步的處理異步無非是通知系統做一件事情。然后忘掉它,自己做其他事情去了。很多時候系統做完某一件事情后需要一些后續的操作。怎么辦?這時候就是告訴異步調用如何做后續處理。通常有兩種方式:
將來式: 當你希望主線程發起異步調用,并輪詢等待結果的時候使用將來式;
回調式: 常說的異步回調就是它。
以文件讀取為例
將來式將來式用現有的Java.util.concurrent技術聲明一個Future,用來保存異步操作的處理結果。通常用Future get()方法(帶或不帶超時參數)在異步IO操作完成時獲取其結果。
AsynchronousFileChannel會關聯線程池,它的任務是接收IO處理事件,并分發給負責處理通道中IO操作結果的結果處理器。跟通道中發起的IO操作關聯的結果處理器確保是由線程池中的某個線程產生。
將來式例子:
Path path = Paths.get("/data/code/github/java_practice/src/main/resources/1log4j.properties"); AsynchronousFileChannel channel = AsynchronousFileChannel.open(path); ByteBuffer buffer = ByteBuffer.allocate(1024); Future回調式future = channel.read(buffer,0); // while (!future.isDone()){ // System.out.println("I"m idle"); // } Integer readNumber = future.get(); buffer.flip(); CharBuffer charBuffer = CharBuffer.allocate(1024); CharsetDecoder decoder = Charset.defaultCharset().newDecoder(); decoder.decode(buffer,charBuffer,false); charBuffer.flip(); String data = new String(charBuffer.array(),0, charBuffer.limit()); System.out.println("read number:" + readNumber); System.out.println(data);
回調式所采用的事件處理技術類似于Swing UI編程采用的機制。基本思想是主線程會派一個偵查員CompletionHandler到獨立的線程中執行IO操作。這個偵查員將帶著IO的操作的結果返回到主線程中,這個結果會觸發它自己的completed或failed方法(要重寫這兩個方法)。在異步IO活動結束后,接口java.nio.channels.CompletionHandler會被調用,其中V是結果類型,A是提供結果的附著對象。此時必須已經有了該接口completed(V,A)和failed(V,A)方法的實現,你的程序才能知道異步IO操作成功或失敗時該如何處理。
回調式例子:
Path path = Paths.get("/data/code/github/java_practice/src/main/resources/1log4j.properties"); AsynchronousFileChannel channel = AsynchronousFileChannel.open(path); ByteBuffer buffer = ByteBuffer.allocate(1024); channel.read(buffer, 0, buffer, new CompletionHandler異步socket client操作() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println(Thread.currentThread().getName() + " read success!"); } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("read error"); } }); while (true){ System.out.println(Thread.currentThread().getName() + " sleep"); Thread.sleep(1000); }
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); channel.connect(new InetSocketAddress("127.0.0.1",8888)).get(); ByteBuffer buffer = ByteBuffer.wrap("中文,你好".getBytes()); Future異步socket server操作future = channel.write(buffer); future.get(); System.out.println("send ok");
final AsynchronousServerSocketChannel channel = AsynchronousServerSocketChannel .open() .bind(new InetSocketAddress("0.0.0.0",8888)); channel.accept(null, new CompletionHandler他山之石() { @Override public void completed(final AsynchronousSocketChannel client, Void attachment) { channel.accept(null, this); ByteBuffer buffer = ByteBuffer.allocate(1024); client.read(buffer, buffer, new CompletionHandler () { @Override public void completed(Integer result_num, ByteBuffer attachment) { attachment.flip(); CharBuffer charBuffer = CharBuffer.allocate(1024); CharsetDecoder decoder = Charset.defaultCharset().newDecoder(); decoder.decode(attachment,charBuffer,false); charBuffer.flip(); String data = new String(charBuffer.array(),0, charBuffer.limit()); System.out.println("read data:" + data); try{ client.close(); }catch (Exception e){} } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("read error"); } }); } @Override public void failed(Throwable exc, Void attachment) { System.out.println("accept error"); } }); while (true){ Thread.sleep(1000); }
java中的NIO: http://www.jianshu.com/p/a33f741fe450
Unix下五種IO模型:
http://www.cnblogs.com/virusolf/p/4946975.html
IO設計模式: Reactor和Proactor對比:
https://segmentfault.com/a/1190000002715832
proactor: http://www.laputan.org/pub/sag/proactor.pdf
Java7中增加的新特性:
http://wn398.github.io/2014/04/01/Java7%E4%B8%AD%E5%A2%9E%E5%8A%A0%E7%9A%84%E6%96%B0%E7%89%B9%E6%80%A7/
基于Java NIO2實現的異步非阻塞消息通信框架:
http://codepub.cn/2016/02/26/Asynchronous-non-blocking-message-communication-framework-based-on-Java-NIO2/
Java新一代網絡編程模型AIO原理及Linux系統AIO介紹:
http://www.52im.net/thread-306-1-1.html
java aio 編程: http://colobu.com/2014/11/13/java-aio-introduction/
[高并發Java 八] NIO和AIO: https://my.oschina.net/hosee/blog/615269
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66289.html
摘要:之后推出的是,是面向緩沖區的,數據讀取到一個它稍后處理的緩沖區,需要時可在緩沖區中前后移動。之后的又引入了,對應的可以實現模式。該接口常被用于高效的網絡文件的數據傳輸和大文件拷貝。進階五模型從到和模式 Linux I/O model blocking I/O non blocking I/O I/O multiplexing (select and poll) signal driv...
摘要:后改良為用線程池的方式代替新增線程,被稱為偽異步。最大的問題是阻塞,同步。每次請求都由程序執行并返回,這是同步的缺陷。這些都會被注冊在多路復用器上。多路復用器提供選擇已經就緒狀態任務的能力。并沒有采用的多路復用器,而是使用異步通道的概念。 Netty是一個提供異步事件驅動的網絡應用框架,用以快速開發高性能、高可靠的網絡服務器和客戶端程序。Netty簡化了網絡程序的開發,是很多框架和公司...
摘要:后改良為用線程池的方式代替新增線程,被稱為偽異步。最大的問題是阻塞,同步。每次請求都由程序執行并返回,這是同步的缺陷。這些都會被注冊在多路復用器上。多路復用器提供選擇已經就緒狀態任務的能力。并沒有采用的多路復用器,而是使用異步通道的概念。 Netty是一個提供異步事件驅動的網絡應用框架,用以快速開發高性能、高可靠的網絡服務器和客戶端程序。Netty簡化了網絡程序的開發,是很多框架和公司...
摘要:即可以理解為,方法都是異步的,完成后會主動調用回調函數。主要在包下增加了下面四個異步通道其中的方法,會返回一個帶回調函數的對象,當執行完讀取寫入操作后,直接調用回調函數。 本文原創地址,我的博客:jsbintask.cn/2019/04/16/…(食用效果最佳),轉載請注明出處! 在理解什么是BIO,NIO,AIO之前,我們首先需要了解什么是同步,異步,阻塞,非阻塞。假如我們現在要去銀行取...
摘要:三同步非阻塞式以塊的方式處理數據面向緩存區的采用多路復用模式基于事件驅動是實現了的一個流行框架,的。阿里云分布式文件系統里用的就是。四異步非阻塞式基于事件驅動,不需要多路復用器對注冊通道進行輪詢,采用設計模式。 一、什么是IO IO 輸入、輸出 (read write accept)IO是面向流的 二、BIO BIO是同步阻塞式IO 服務端與客戶端進行三次握手后一個鏈路建立一個線程面...
閱讀 1074·2021-11-19 09:40
閱讀 2213·2021-11-15 18:00
閱讀 1267·2021-10-18 13:34
閱讀 2248·2021-09-02 15:40
閱讀 1533·2019-08-30 14:01
閱讀 1113·2019-08-30 11:11
閱讀 2482·2019-08-29 15:26
閱讀 722·2019-08-29 14:15