Java中AIO、BIO、NIO應(yīng)用場(chǎng)景及區(qū)別
一、AIO、BIO、NIO 的區(qū)別
AIO(異步 I/O):AIO 是 Java NIO 2 中新增的一種 I/O 模式,它的特點(diǎn)是 I/O 操作不會(huì)阻塞線(xiàn)程,而是在后臺(tái)由操作系統(tǒng)完成,完成后會(huì)通知應(yīng)用程序。AIO 可以讓?xiě)?yīng)用程序在等待 I/O 完成時(shí)執(zhí)行其他任務(wù),提高了系統(tǒng)的并發(fā)性能。AIO 適用于高并發(fā)的網(wǎng)絡(luò)應(yīng)用,比如聊天室、多人在線(xiàn)游戲等。
BIO(阻塞 I/O):BIO 是 Java 中最早的一種 I/O 模式,它的特點(diǎn)是 I/O 操作會(huì)阻塞線(xiàn)程,直到 I/O 操作完成。BIO 的缺點(diǎn)是并發(fā)性能較差,因?yàn)槊總€(gè)線(xiàn)程都會(huì)阻塞等待 I/O 完成。BIO 適用于連接數(shù)較少的網(wǎng)絡(luò)應(yīng)用,比如 Web 應(yīng)用中的 Servlet。
NIO(非阻塞 I/O):NIO 是 Java 中的一種 I/O 模式,它的特點(diǎn)是 I/O 操作不會(huì)阻塞線(xiàn)程,但是需要輪詢(xún)操作系統(tǒng)的 I/O 事件來(lái)判斷是否有 I/O 操作完成。NIO 可以讓?xiě)?yīng)用程序在等待 I/O 完成時(shí)執(zhí)行其他任務(wù),提高了系統(tǒng)的并發(fā)性能。NIO 適用于連接數(shù)較多、并發(fā)性要求較高的網(wǎng)絡(luò)應(yīng)用,比如高性能的服務(wù)器應(yīng)用、網(wǎng)關(guān)應(yīng)用等。
二、應(yīng)用場(chǎng)景
AIO、BIO、NIO 適用于 Java 網(wǎng)絡(luò)編程,可以用于開(kāi)發(fā)各種網(wǎng)絡(luò)應(yīng)用。以下是它們的一些應(yīng)用場(chǎng)景:
AIO:適用于高并發(fā)的網(wǎng)絡(luò)應(yīng)用,比如聊天室、多人在線(xiàn)游戲等。
BIO:適用于連接數(shù)較少的網(wǎng)絡(luò)應(yīng)用,比如 Web 應(yīng)用中的 Servlet。
NIO:適用于連接數(shù)較多、并發(fā)性要求較高的網(wǎng)絡(luò)應(yīng)用,比如高性能的服務(wù)器應(yīng)用、網(wǎng)關(guān)應(yīng)用等。
三、NIO 的舉例
假設(shè)有一個(gè)服務(wù)器需要同時(shí)處理多個(gè)客戶(hù)端請(qǐng)求,傳統(tǒng)的 BIO 模式需要為每個(gè)客戶(hù)端請(qǐng)求創(chuàng)建一個(gè)線(xiàn)程,這樣會(huì)導(dǎo)致線(xiàn)程數(shù)量過(guò)多,占用大量的系統(tǒng)資源。而 NIO 模式可以通過(guò)單線(xiàn)程處理多個(gè)客戶(hù)端請(qǐng)求,極大地減少了線(xiàn)程數(shù)量,提高了系統(tǒng)的并發(fā)性能(詳細(xì)可了解后面的IO多路復(fù)用)。
具體實(shí)現(xiàn)方法是,使用 NIO 的 Selector 對(duì)象來(lái)監(jiān)聽(tīng)多個(gè)通道的事件,當(dāng)某個(gè)通道有事件發(fā)生時(shí),Selector 會(huì)通知應(yīng)用程序處理該事件。下面是一個(gè)簡(jiǎn)單的 NIO 服務(wù)器實(shí)現(xiàn)代碼:
package com.pany.camp.io; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class NIOServer { ? ? public static void main(String[] args) throws IOException { ? ? ? ? // 創(chuàng)建一個(gè) Selector 對(duì)象 ? ? ? ? Selector selector = Selector.open(); ? ? ? ? // 創(chuàng)建一個(gè) ServerSocketChannel 對(duì)象,并綁定到指定端口 ? ? ? ? ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ? ? ? ? serverSocketChannel.socket().bind(new InetSocketAddress(8080)); ? ? ? ? serverSocketChannel.configureBlocking(false); ? ? ? ? // 將 ServerSocketChannel 注冊(cè)到 Selector 中,監(jiān)聽(tīng) ACCEPT 事件 ? ? ? ? serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); ? ? ? ? while (true) { ? ? ? ? ? ? // 阻塞等待事件發(fā)生 ? ? ? ? ? ? selector.select(); ? ? ? ? ? ? // 處理事件 ? ? ? ? ? ? Set<SelectionKey> selectionKeys = selector.selectedKeys(); ? ? ? ? ? ? Iterator<SelectionKey> iterator = selectionKeys.iterator(); ? ? ? ? ? ? while (iterator.hasNext()) { ? ? ? ? ? ? ? ? SelectionKey selectionKey = iterator.next(); ? ? ? ? ? ? ? ? if (selectionKey.isAcceptable()) { ? ? ? ? ? ? ? ? ? ? // 處理 ACCEPT 事件 ? ? ? ? ? ? ? ? ? ? ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel(); ? ? ? ? ? ? ? ? ? ? SocketChannel socketChannel = ssc.accept(); ? ? ? ? ? ? ? ? ? ? socketChannel.configureBlocking(false); ? ? ? ? ? ? ? ? ? ? socketChannel.register(selector, SelectionKey.OP_READ); ? ? ? ? ? ? ? ? } else if (selectionKey.isReadable()) { ? ? ? ? ? ? ? ? ? ? // 處理 READ 事件 ? ? ? ? ? ? ? ? ? ? SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ? ? ? ? ? ? ? ? ? ? ByteBuffer buffer = ByteBuffer.allocate(1024); ? ? ? ? ? ? ? ? ? ? socketChannel.read(buffer); ? ? ? ? ? ? ? ? ? ? buffer.flip(); ? ? ? ? ? ? ? ? ? ? System.out.println("Received message: " + new String(buffer.array())); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? // 處理完事件后,將該事件從 selectedKeys 集合中移除 ? ? ? ? ? ? ? ? iterator.remove(); ? ? ? ? ? ? } ? ? ? ? } ? ? } }
以上代碼創(chuàng)建了一個(gè) NIO 服務(wù)器,使用單線(xiàn)程處理多個(gè)客戶(hù)端請(qǐng)求。當(dāng)有客戶(hù)端連接時(shí),會(huì)觸發(fā) ACCEPT 事件,將該客戶(hù)端的 SocketChannel 注冊(cè)到 Selector 中,監(jiān)聽(tīng) READ 事件。當(dāng)客戶(hù)端發(fā)送數(shù)據(jù)時(shí),會(huì)觸發(fā) READ 事件,服務(wù)器可以讀取客戶(hù)端發(fā)送的數(shù)據(jù)并進(jìn)行處理。
四、NIO 在 Netty 中的使用
Netty 是一個(gè)基于 NIO 的高性能網(wǎng)絡(luò)編程框架,它封裝了 NIO 的底層細(xì)節(jié),提供了更加簡(jiǎn)單易用的 API,使得開(kāi)發(fā)高性能的網(wǎng)絡(luò)應(yīng)用變得更加容易。下面是 Netty 中 NIO 的一些應(yīng)用:
Channel:在 Netty 中,Channel 是 NIO 中的 SocketChannel 的封裝,它提供了更加簡(jiǎn)單易用的 API,比如可以通過(guò) ChannelPipeline 來(lái)實(shí)現(xiàn)數(shù)據(jù)的編解碼、流量控制、拆包粘包等功能。
EventLoop:在 Netty 中,EventLoop 是 NIO 中的 Selector 的封裝,它負(fù)責(zé)處理所有的 I/O 事件,包括連接、讀、寫(xiě)等事件。通過(guò) EventLoop 的多線(xiàn)程處理能力,可以實(shí)現(xiàn)高并發(fā)的網(wǎng)絡(luò)應(yīng)用。
ByteBuf:在 Netty 中,ByteBuf 是 NIO 中的 ByteBuffer 的封裝,它提供了更加靈活的內(nèi)存管理方式,可以實(shí)現(xiàn)零拷貝的數(shù)據(jù)傳輸。
ChannelFuture:在 Netty 中,ChannelFuture 是 NIO 中的 Future 的封裝,它提供了更加簡(jiǎn)單易用的異步編程方式,可以實(shí)現(xiàn)非阻塞的網(wǎng)絡(luò)應(yīng)用。
ChannelHandlerContext:在 Netty 中,ChannelHandlerContext 是 ChannelPipeline 中的一個(gè)節(jié)點(diǎn),它提供了更加靈活的事件處理方式,可以實(shí)現(xiàn)自定義的數(shù)據(jù)編解碼、流量控制、拆包粘包等功能。
Netty 是一個(gè)基于 NIO 的高性能網(wǎng)絡(luò)編程框架,它封裝了 NIO 的底層細(xì)節(jié),提供了更加簡(jiǎn)單易用的 API,使得開(kāi)發(fā)高性能的網(wǎng)絡(luò)應(yīng)用變得更加容易。
到此這篇關(guān)于Java中AIO、BIO、NIO應(yīng)用場(chǎng)景及區(qū)別的文章就介紹到這了,更多相關(guān)Java AIO BIO NIO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Jmeter進(jìn)行http接口測(cè)試的詳細(xì)流程
本文主要針對(duì)http接口進(jìn)行測(cè)試,使用Jmeter工具實(shí)現(xiàn), Jmter工具設(shè)計(jì)之初是用于做性能測(cè)試的,它在實(shí)現(xiàn)對(duì)各種接口的調(diào)用方面已經(jīng)做的比較成熟,因此,本次直接使用Jmeter工具來(lái)完成對(duì)Http接口的測(cè)試,需要的朋友可以參考下2024-12-12SpringBoot應(yīng)用部署于外置Tomcat容器的方法
這篇文章主要介紹了SpringBoot應(yīng)用部署于外置Tomcat容器的方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-06-06使用注解@Recover優(yōu)化丑陋的循環(huán)詳解
我們知道在實(shí)現(xiàn)一個(gè)功能的時(shí)候是可以使用不同的代碼來(lái)實(shí)現(xiàn)的,那么相應(yīng)的不同實(shí)現(xiàn)方法的性能肯定也是有差別的,下面這篇文章主要給大家介紹了關(guān)于使用注解@Recover優(yōu)化丑陋的循環(huán)的相關(guān)資料,需要的朋友可以參考下2022-04-04spring?和?idea?建議不要使用?@Autowired注解的原因解析
@Autowired?是Spring框架的注解,而@Resource是JavaEE的注解,這篇文章主要介紹了spring和idea建議不要使用@Autowired注解的相關(guān)知識(shí),需要的朋友可以參考下2023-11-11詳解Java如何實(shí)現(xiàn)多線(xiàn)程步調(diào)一致
本章節(jié)主要講解另外兩個(gè)線(xiàn)程同步器:CountDownLatch和CyclicBarrier的用法,使用場(chǎng)景以及實(shí)現(xiàn)原理,感興趣的小伙伴可以了解一下2023-07-07springboot創(chuàng)建線(xiàn)程池的兩種方式小結(jié)
這篇文章主要介紹了springboot創(chuàng)建線(xiàn)程池的兩種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12