日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

java aio_java中的AIO

發(fā)布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java aio_java中的AIO 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

jdk7中新增了一些與文件(網(wǎng)絡(luò))I/O相關(guān)的一些api。這些API被稱為NIO.2,或稱為AIO(Asynchronous I/O)。AIO最大的一個特性就是異步能力,這種能力對socket與文件I/O都起作用。AIO其實(shí)是一種在讀寫操作結(jié)束之前允許進(jìn)行其他操作的I/O處理。AIO是對JDK1.4中提出的同步非阻塞I/O(NIO)的進(jìn)一步增強(qiáng)。

關(guān)于NIO,之前的一篇文章可以看看:java中的NIO

jdk7主要增加了三個新的異步通道:

AsynchronousFileChannel: 用于文件異步讀寫;

AsynchronousSocketChannel: 客戶端異步socket;

AsynchronousServerSocketChannel: 服務(wù)器異步socket。

因?yàn)锳IO的實(shí)施需充分調(diào)用OS參與,IO需要操作系統(tǒng)支持、并發(fā)也同樣需要操作系統(tǒng)的支持,所以性能方面不同操作系統(tǒng)差異會比較明顯。

前提概念

在具體看AIO之前,我們需要知道一些必要的前提概念。

Unix中的I/O模型

Unix定義了五種I/O模型

阻塞I/O

非阻塞I/O

I/O復(fù)用(select、poll、linux 2.6種改進(jìn)的epoll)

信號驅(qū)動IO(SIGIO)

異步I/O(POSIX的aio_系列函數(shù))

一個戲謔的例子:

如果你想吃一份宮保雞丁蓋飯:

同步阻塞:你到飯館點(diǎn)餐,然后在那等著,還要一邊喊:好了沒啊!

同步非阻塞:在飯館點(diǎn)完餐,就去遛狗了。不過溜一會兒,就回飯館喊一聲:好了沒啊!

異步阻塞:遛狗的時候,接到飯館電話,說飯做好了,讓您親自去拿。

異步非阻塞:飯館打電話說,我們知道您的位置,一會給你送過來,安心遛狗就可以了。

詳情參見文章末尾的他山之石-Unix下五種IO模型。

Reactor與Proactor

兩種IO多路復(fù)用方案:Reactor and Proactor。

Reactor模式是基于同步I/O的,而Proactor模式是和異步I/O相關(guān)的。

reactor:能收了你跟俺說一聲。proactor: 你給我收十個字節(jié),收好了跟俺說一聲。

詳情參見文章末尾的他山之石-IO設(shè)計(jì)模式:Reactor和Proactor對比。

異步的處理

異步無非是通知系統(tǒng)做一件事情。然后忘掉它,自己做其他事情去了。很多時候系統(tǒng)做完某一件事情后需要一些后續(xù)的操作。怎么辦?這時候就是告訴異步調(diào)用如何做后續(xù)處理。通常有兩種方式:

將來式: 當(dāng)你希望主線程發(fā)起異步調(diào)用,并輪詢等待結(jié)果的時候使用將來式;

回調(diào)式: 常說的異步回調(diào)就是它。

以文件讀取為例

將來式

將來式用現(xiàn)有的Java.util.concurrent技術(shù)聲明一個Future,用來保存異步操作的處理結(jié)果。通常用Future get()方法(帶或不帶超時參數(shù))在異步IO操作完成時獲取其結(jié)果。

AsynchronousFileChannel會關(guān)聯(lián)線程池,它的任務(wù)是接收IO處理事件,并分發(fā)給負(fù)責(zé)處理通道中IO操作結(jié)果的結(jié)果處理器。跟通道中發(fā)起的IO操作關(guān)聯(lián)的結(jié)果處理器確保是由線程池中的某個線程產(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 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)式

回調(diào)式所采用的事件處理技術(shù)類似于Swing UI編程采用的機(jī)制。基本思想是主線程會派一個偵查員CompletionHandler到獨(dú)立的線程中執(zhí)行IO操作。這個偵查員將帶著IO的操作的結(jié)果返回到主線程中,這個結(jié)果會觸發(fā)它自己的completed或failed方法(要重寫這兩個方法)。在異步IO活動結(jié)束后,接口java.nio.channels.CompletionHandler會被調(diào)用,其中V是結(jié)果類型,A是提供結(jié)果的附著對象。此時必須已經(jīng)有了該接口completed(V,A)和failed(V,A)方法的實(shí)現(xiàn),你的程序才能知道異步IO操作成功或失敗時該如何處理。

回調(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() {

@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);

}

異步socket client操作

AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();

channel.connect(new InetSocketAddress("127.0.0.1",8888)).get();

ByteBuffer buffer = ByteBuffer.wrap("中文,你好".getBytes());

Future future = channel.write(buffer);

future.get();

System.out.println("send ok");

異步socket server操作

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);

}

他山之石

總結(jié)

以上是生活随笔為你收集整理的java aio_java中的AIO的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。