您好,登錄后才能下訂單哦!
Java中怎么實(shí)現(xiàn)AIO異步網(wǎng)絡(luò)編程,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
AIO中的A即Asynchronous,AIO即異步IO。它是異步非阻塞的,客戶端的I/O請(qǐng)求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理,一般我們的業(yè)務(wù)處理邏輯會(huì)變成一個(gè)回調(diào)函數(shù),等待IO操作完成后,由系統(tǒng)自動(dòng)觸發(fā)。
在進(jìn)行讀寫操作時(shí),只需直接調(diào)用API的read/write方法即可。這兩種方法均為異步的,對(duì)于讀操作而言,當(dāng)有流可讀取時(shí),操作系統(tǒng)會(huì)將可讀的流傳入read方法的緩沖區(qū),并通知應(yīng)用程序;對(duì)于寫操作而言,當(dāng)操作系統(tǒng)將write方法傳遞的流寫入完畢時(shí),操作系統(tǒng)主動(dòng)通知應(yīng)用程序。即可以理解為,read/write方法都是異步的,完成后會(huì)主動(dòng)調(diào)用回調(diào)函數(shù)。
AIO其實(shí)是對(duì)NIO的增強(qiáng),新增了許多支持異步的類如AsynchronousServerSocketChannel,AsynchronousChannel,AsynchronousChannelGroup,CompletionHandler等。
在Linux系統(tǒng)中AIO和NIO的底層實(shí)現(xiàn)都是epoll,epoll本身是輪詢模型,AIO只不過是對(duì)epoll又包了一層,而在windows系統(tǒng)中AIO是通過IOCP(完成端口)實(shí)現(xiàn)。而目前大多數(shù)的服務(wù)器都是Linux系統(tǒng),這也是Netty中使用NIO而非AIO的一個(gè)原因,在實(shí)際使用中由于操作系統(tǒng)的差異,AIO的性能有時(shí)并沒有NIO高效,因此AIO的使用并沒有很廣泛。
AIO服務(wù)端代碼示例:
public class AIOServer {
public static void main(String[] args) throws IOException {
// 多線程版本
// ExecutorService executorService = Executors.newCachedThreadPool();
// AsynchronousChannelGroup channelGroup =
// AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
// AsynchronousServerSocketChannel serverSocketChannel =
// AsynchronousServerSocketChannel.open(channelGroup).bind(new
// InetSocketAddress(8080));
// 單線程版本
AsynchronousServerSocketChannel serverSocketChannel =
AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080));
serverSocketChannel.accept(
null,
new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel client, Object attachment) {
serverSocketChannel.accept(null, this);
try {
System.out.println(client.getRemoteAddress());
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
client.read(
byteBuffer,
byteBuffer,
new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
byte[] content = new byte[attachment.limit()];
attachment.get(content);
System.out.println(new String(content));
try {
System.out.println("Client: " + client.getRemoteAddress());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("failed: " + exc.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {}
});
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
AIO客戶端代碼示例:
public class AIOClient {
public static void main(String[] args) throws Exception {
AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open();
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080));
Thread.sleep(1000);
ByteBuffer buffer = ByteBuffer.wrap("Hello Server".getBytes());
socketChannel.write(buffer).get();
}
}
看完上述內(nèi)容,你們掌握J(rèn)ava中怎么實(shí)現(xiàn)AIO異步網(wǎng)絡(luò)編程的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。