摘要:會(huì)關(guān)聯(lián)線程池,它的任務(wù)是接收處理事件,并分發(fā)給負(fù)責(zé)處理通道中操作結(jié)果的結(jié)果處理器。跟通道中發(fā)起的操作關(guān)聯(lián)的結(jié)果處理器確保是由線程池中的某個(gè)線程產(chǎn)生?;舅枷胧侵骶€程會(huì)派一個(gè)偵查員到獨(dú)立的線程中執(zhí)行操作。
簡介
jdk7中新增了一些與文件(網(wǎng)絡(luò))I/O相關(guān)的一些api。這些API被稱為NIO.2,或稱為AIO(Asynchronous I/O)。AIO最大的一個(gè)特性就是異步能力,這種能力對(duì)socket與文件I/O都起作用。AIO其實(shí)是一種在讀寫操作結(jié)束之前允許進(jìn)行其他操作的I/O處理。AIO是對(duì)JDK1.4中提出的同步非阻塞I/O(NIO)的進(jìn)一步增強(qiáng)。
關(guān)于NIO,之前的一篇文章可以看看:java中的NIO
jdk7主要增加了三個(gè)新的異步通道:
AsynchronousFileChannel: 用于文件異步讀寫;
AsynchronousSocketChannel: 客戶端異步socket;
AsynchronousServerSocketChannel: 服務(wù)器異步socket。
因?yàn)锳IO的實(shí)施需充分調(diào)用OS參與,IO需要操作系統(tǒng)支持、并發(fā)也同樣需要操作系統(tǒng)的支持,所以性能方面不同操作系統(tǒng)差異會(huì)比較明顯。
前提概念在具體看AIO之前,我們需要知道一些必要的前提概念。
Unix中的I/O模型Unix定義了五種I/O模型
阻塞I/O
非阻塞I/O
I/O復(fù)用(select、poll、linux 2.6種改進(jìn)的epoll)
信號(hào)驅(qū)動(dòng)IO(SIGIO)
異步I/O(POSIX的aio_系列函數(shù))
一個(gè)戲謔的例子:
如果你想吃一份宮保雞丁蓋飯:
同步阻塞:你到飯館點(diǎn)餐,然后在那等著,還要一邊喊:好了沒啊!
同步非阻塞:在飯館點(diǎn)完餐,就去遛狗了。不過溜一會(huì)兒,就回飯館喊一聲:好了沒?。?/p>
異步阻塞:遛狗的時(shí)候,接到飯館電話,說飯做好了,讓您親自去拿。
異步非阻塞:飯館打電話說,我們知道您的位置,一會(huì)給你送過來,安心遛狗就可以了。
詳情參見文章末尾的他山之石-Unix下五種IO模型。
Reactor與Proactor兩種IO多路復(fù)用方案:Reactor and Proactor。
Reactor模式是基于同步I/O的,而Proactor模式是和異步I/O相關(guān)的。
reactor:能收了你跟俺說一聲。proactor: 你給我收十個(gè)字節(jié),收好了跟俺說一聲。
詳情參見文章末尾的他山之石-IO設(shè)計(jì)模式:Reactor和Proactor對(duì)比。
異步的處理異步無非是通知系統(tǒng)做一件事情。然后忘掉它,自己做其他事情去了。很多時(shí)候系統(tǒng)做完某一件事情后需要一些后續(xù)的操作。怎么辦?這時(shí)候就是告訴異步調(diào)用如何做后續(xù)處理。通常有兩種方式:
將來式: 當(dāng)你希望主線程發(fā)起異步調(diào)用,并輪詢等待結(jié)果的時(shí)候使用將來式;
回調(diào)式: 常說的異步回調(diào)就是它。
以文件讀取為例
將來式將來式用現(xiàn)有的Java.util.concurrent技術(shù)聲明一個(gè)Future,用來保存異步操作的處理結(jié)果。通常用Future get()方法(帶或不帶超時(shí)參數(shù))在異步IO操作完成時(shí)獲取其結(jié)果。
AsynchronousFileChannel會(huì)關(guān)聯(lián)線程池,它的任務(wù)是接收IO處理事件,并分發(fā)給負(fù)責(zé)處理通道中IO操作結(jié)果的結(jié)果處理器。跟通道中發(fā)起的IO操作關(guān)聯(lián)的結(jié)果處理器確保是由線程池中的某個(gè)線程產(chǎn)生。
將來式例子:
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回調(diào)式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);
回調(diào)式所采用的事件處理技術(shù)類似于Swing UI編程采用的機(jī)制?;舅枷胧侵骶€程會(huì)派一個(gè)偵查員CompletionHandler到獨(dú)立的線程中執(zhí)行IO操作。這個(gè)偵查員將帶著IO的操作的結(jié)果返回到主線程中,這個(gè)結(jié)果會(huì)觸發(fā)它自己的completed或failed方法(要重寫這兩個(gè)方法)。在異步IO活動(dòng)結(jié)束后,接口java.nio.channels.CompletionHandler會(huì)被調(diào)用,其中V是結(jié)果類型,A是提供結(jié)果的附著對(duì)象。此時(shí)必須已經(jīng)有了該接口completed(V,A)和failed(V,A)方法的實(shí)現(xiàn),你的程序才能知道異步IO操作成功或失敗時(shí)該如何處理。
回調(diào)式例子:
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設(shè)計(jì)模式: Reactor和Proactor對(duì)比:
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實(shí)現(xiàn)的異步非阻塞消息通信框架:
http://codepub.cn/2016/02/26/Asynchronous-non-blocking-message-communication-framework-based-on-Java-NIO2/
Java新一代網(wǎng)絡(luò)編程模型AIO原理及Linux系統(tǒng)AIO介紹:
http://www.52im.net/thread-306-1-1.html
java aio 編程: http://colobu.com/2014/11/13/java-aio-introduction/
[高并發(fā)Java 八] NIO和AIO: https://my.oschina.net/hosee/blog/615269
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66289.html
摘要:之后推出的是,是面向緩沖區(qū)的,數(shù)據(jù)讀取到一個(gè)它稍后處理的緩沖區(qū),需要時(shí)可在緩沖區(qū)中前后移動(dòng)。之后的又引入了,對(duì)應(yīng)的可以實(shí)現(xiàn)模式。該接口常被用于高效的網(wǎng)絡(luò)文件的數(shù)據(jù)傳輸和大文件拷貝。進(jìn)階五模型從到和模式 Linux I/O model blocking I/O non blocking I/O I/O multiplexing (select and poll) signal driv...
摘要:后改良為用線程池的方式代替新增線程,被稱為偽異步。最大的問題是阻塞,同步。每次請(qǐng)求都由程序執(zhí)行并返回,這是同步的缺陷。這些都會(huì)被注冊(cè)在多路復(fù)用器上。多路復(fù)用器提供選擇已經(jīng)就緒狀態(tài)任務(wù)的能力。并沒有采用的多路復(fù)用器,而是使用異步通道的概念。 Netty是一個(gè)提供異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,用以快速開發(fā)高性能、高可靠的網(wǎng)絡(luò)服務(wù)器和客戶端程序。Netty簡化了網(wǎng)絡(luò)程序的開發(fā),是很多框架和公司...
摘要:后改良為用線程池的方式代替新增線程,被稱為偽異步。最大的問題是阻塞,同步。每次請(qǐng)求都由程序執(zhí)行并返回,這是同步的缺陷。這些都會(huì)被注冊(cè)在多路復(fù)用器上。多路復(fù)用器提供選擇已經(jīng)就緒狀態(tài)任務(wù)的能力。并沒有采用的多路復(fù)用器,而是使用異步通道的概念。 Netty是一個(gè)提供異步事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架,用以快速開發(fā)高性能、高可靠的網(wǎng)絡(luò)服務(wù)器和客戶端程序。Netty簡化了網(wǎng)絡(luò)程序的開發(fā),是很多框架和公司...
摘要:即可以理解為,方法都是異步的,完成后會(huì)主動(dòng)調(diào)用回調(diào)函數(shù)。主要在包下增加了下面四個(gè)異步通道其中的方法,會(huì)返回一個(gè)帶回調(diào)函數(shù)的對(duì)象,當(dāng)執(zhí)行完讀取寫入操作后,直接調(diào)用回調(diào)函數(shù)。 本文原創(chuàng)地址,我的博客:jsbintask.cn/2019/04/16/…(食用效果最佳),轉(zhuǎn)載請(qǐng)注明出處! 在理解什么是BIO,NIO,AIO之前,我們首先需要了解什么是同步,異步,阻塞,非阻塞。假如我們現(xiàn)在要去銀行取...
摘要:三同步非阻塞式以塊的方式處理數(shù)據(jù)面向緩存區(qū)的采用多路復(fù)用模式基于事件驅(qū)動(dòng)是實(shí)現(xiàn)了的一個(gè)流行框架,的。阿里云分布式文件系統(tǒng)里用的就是。四異步非阻塞式基于事件驅(qū)動(dòng),不需要多路復(fù)用器對(duì)注冊(cè)通道進(jìn)行輪詢,采用設(shè)計(jì)模式。 一、什么是IO IO 輸入、輸出 (read write accept)IO是面向流的 二、BIO BIO是同步阻塞式IO 服務(wù)端與客戶端進(jìn)行三次握手后一個(gè)鏈路建立一個(gè)線程面...
閱讀 1109·2021-11-19 09:40
閱讀 2251·2021-11-15 18:00
閱讀 1302·2021-10-18 13:34
閱讀 2280·2021-09-02 15:40
閱讀 1567·2019-08-30 14:01
閱讀 1141·2019-08-30 11:11
閱讀 2505·2019-08-29 15:26
閱讀 753·2019-08-29 14:15