最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中BIO、NIO和AIO舉例總結(jié)

 更新時(shí)間:2026年02月24日 10:47:10   作者:Binary-Jeff  
Java BIO、NIO、AIO是 Java 中的三種I/O模式,每種模式都有其特點(diǎn)和應(yīng)用場(chǎng)景,這篇文章主要介紹了Java中BIO、NIO和AIO的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在講 BIO,NIO,AIO 之前先來回顧一下這樣幾個(gè)概念:同步與異步,阻塞與非阻塞。

1.同步與異步

  • 同步調(diào)用(Synchronous Cal): 同步就是發(fā)起一個(gè)調(diào)用后,被調(diào)用者未處理完請(qǐng)求之前,調(diào)用不返回        

代碼示例:

int result = calculateSum(3, 5); // 等到函數(shù)調(diào)用完成后,獲取返回結(jié)果
System.out.println(result);      // 輸出計(jì)算結(jié)果 8

public static int calculateSum(int a, int b) {
    // 同步調(diào)用:當(dāng)前線程會(huì)阻塞,直到函數(shù)計(jì)算完成并返回結(jié)果
    return a + b;
}
  • 異步調(diào)用(Asynchronous Call): 異步就是發(fā)起一個(gè)調(diào)用后,立刻得到被調(diào)用者的回應(yīng)表示已接收到請(qǐng)求,但是被調(diào)用者并沒有返回結(jié)果,此時(shí)我們可以處理其他的請(qǐng)求,被調(diào)用者通常依靠事件,回調(diào)等機(jī)制來通知調(diào)用者其返回結(jié)果。

代碼示例(使用回調(diào)):  調(diào)用者傳遞一個(gè)函數(shù)給被調(diào)用者,被調(diào)用者在完成后調(diào)用該函數(shù)。

interface Callback {
    void onComplete(int result);
}

void calculateSumAsync(int a, int b, Callback callback) {
    new Thread(() -> {
        int result = a + b;
        callback.onComplete(result); // 完成后通知調(diào)用者
    }).start();
}

// 調(diào)用
calculateSumAsync(3, 5, (result) -> System.out.println("結(jié)果: " + result));

代碼示例(使用事件):被調(diào)用者通過觸發(fā)事件(如按鈕點(diǎn)擊、網(wǎng)絡(luò)請(qǐng)求完成)通知調(diào)用者。

class EventEmitter {
    private List<EventListener> listeners = new ArrayList<>();

    void addListener(EventListener listener) {
        listeners.add(listener);
    }

    void doWork() {
        new Thread(() -> {
            int result = 42;
            for (EventListener listener : listeners) {
                listener.onEvent(result); // 觸發(fā)事件
            }
        }).start();
    }
}

interface EventListener {
    void onEvent(int data);
}

// 調(diào)用
EventEmitter emitter = new EventEmitter();
emitter.addListener(data -> System.out.println("收到事件: " + data));
emitter.doWork();

同步調(diào)用中調(diào)用者發(fā)出請(qǐng)求后,必須阻塞等待被調(diào)用者完成處理并返回結(jié)果,異步調(diào)用中調(diào)用者發(fā)出請(qǐng)求后立即獲得"已接收"響應(yīng),但此時(shí)可能尚未得到最終處理結(jié)果

2.阻塞和非阻塞

  • 阻塞: 阻塞就是發(fā)起一個(gè)請(qǐng)求,調(diào)用者一直等待請(qǐng)求結(jié)果返回,也就是當(dāng)前線程會(huì)被掛起,無法從事其他任務(wù),只有當(dāng)條件就緒才能繼續(xù)。

  • 非阻塞: 非阻塞就是發(fā)起一個(gè)請(qǐng)求,調(diào)用者不用一直等著結(jié)果返回,可以先去干其他事情。

阻塞是指線程在等待某個(gè)條件或資源時(shí)被掛起,不能繼續(xù)執(zhí)行;而非阻塞是指線程不會(huì)被掛起,操作立即返回,能快速判斷是否成功繼續(xù)執(zhí)行。阻塞常用于簡單同步場(chǎng)景,但性能較低;非阻塞適合高并發(fā)環(huán)境,效率更高。

同/異步與阻塞/非阻塞區(qū)別:        

同步與異步主要關(guān)注的是調(diào)用結(jié)果的獲取方式:同步調(diào)用中,調(diào)用方在發(fā)起請(qǐng)求后需要等待操作完成并直接獲得返回結(jié)果;而異步調(diào)用中,調(diào)用方發(fā)起請(qǐng)求后無需立刻獲取結(jié)果,結(jié)果會(huì)在任務(wù)完成后通過回調(diào)、Future 或事件通知等方式返回。
阻塞與非阻塞主要關(guān)注的是等待期間線程的執(zhí)行狀態(tài):阻塞表示線程在等待結(jié)果時(shí)被掛起,無法執(zhí)行其他任務(wù);非阻塞表示線程在等待期間不會(huì)被掛起,仍可以繼續(xù)執(zhí)行其他邏輯。

3.BIO,NIO,AIO

3.1 BIO (Blocking I/O)

BIO 是 Java 早期最經(jīng)典的 I/O 模型,核心特征是 同步 + 阻塞:線程發(fā)起讀/寫后,會(huì)一直阻塞等待數(shù)據(jù)就緒以及拷貝完成,期間不能做其他事情。在服務(wù)端模型中,常見寫法是 一個(gè)連接對(duì)應(yīng)一個(gè)線程(或線程池),實(shí)現(xiàn)簡單但并發(fā)高時(shí)線程開銷大、容易出現(xiàn)上下文切換和資源耗盡問題。

// BIO 服務(wù)端:阻塞式接收 + 阻塞式讀取(一個(gè)連接一個(gè)線程示例)
import java.io.*;
import java.net.*;

public class BioServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(8080);
        System.out.println("BIO server start...");

        while (true) {
            Socket socket = server.accept(); // 阻塞:等待連接
            new Thread(() -> {
                try (BufferedReader in = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                     PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {

                    String line = in.readLine(); // 阻塞:等待數(shù)據(jù)
                    out.println("BIO reply: " + line);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

適用場(chǎng)景:低并發(fā)、連接數(shù)不多、開發(fā)快速驗(yàn)證;或業(yè)務(wù)處理很重、連接少(線程數(shù)可控)。

3.2 NIO (No-Blocking I/O)

NIO 是 Java 1.4 引入的 I/O 框架,對(duì)應(yīng) java.nio 包。NIO 的核心是 同步 + 非阻塞:讀寫調(diào)用可以立即返回(可能讀到 0 字節(jié)),應(yīng)用通過 Selector 多路復(fù)用在一個(gè)線程內(nèi)管理多個(gè)連接,減少線程數(shù)量與上下文切換成本。NIO 采用 Buffer(緩沖區(qū))+ Channel(通道)的方式進(jìn)行數(shù)據(jù)讀寫,并支持阻塞/非阻塞兩種模式,但在高并發(fā)網(wǎng)絡(luò)編程中通常使用 非阻塞 + Selector。

// NIO 服務(wù)端:Selector 多路復(fù)用(單線程處理多個(gè)連接)
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class NioServer {
    public static void main(String[] args) throws Exception {
        ServerSocketChannel server = ServerSocketChannel.open();
        server.bind(new InetSocketAddress(8081));
        server.configureBlocking(false);

        Selector selector = Selector.open();
        server.register(selector, SelectionKey.OP_ACCEPT);

        System.out.println("NIO server start...");

        ByteBuffer buf = ByteBuffer.allocate(1024);

        while (true) {
            selector.select(); // 阻塞等待“就緒事件”(可認(rèn)為等待通知)
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();

            while (it.hasNext()) {
                SelectionKey key = it.next();
                it.remove();

                if (key.isAcceptable()) {
                    SocketChannel sc = server.accept();
                    sc.configureBlocking(false);
                    sc.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel sc = (SocketChannel) key.channel();
                    buf.clear();
                    int n = sc.read(buf); // 非阻塞讀:可能返回 0 或 -1
                    if (n <= 0) {
                        sc.close();
                        continue;
                    }
                    buf.flip();
                    sc.write(ByteBuffer.wrap(("NIO reply: ").getBytes()));
                    sc.write(buf);
                }
            }
        }
    }
}

適用場(chǎng)景:高并發(fā)連接、多連接 I/O 頻繁(網(wǎng)絡(luò)服務(wù)器、網(wǎng)關(guān)、聊天室等),希望用少量線程處理大量連接。

3.3 AIO (Asynchronous I/O)

AIO(也常稱 NIO.2)在 Java 7 引入,對(duì)應(yīng) java.nio.channels.Asynchronous 系列。AIO 的核心特征是 異步 + 非阻塞:應(yīng)用發(fā)起 I/O 操作后立即返回,不需要自己輪詢或等待,操作完成后由系統(tǒng)通過回調(diào)(CompletionHandler)或 Future 通知結(jié)果。相比 NIO 的“同步非阻塞(事件就緒后自己讀寫)”,AIO 更接近“真正的異步”:你只需要提交任務(wù),完成后得到通知。

// AIO 服務(wù)端:異步 accept + 異步 read(回調(diào)驅(qū)動(dòng))
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.concurrent.CountDownLatch;

public class AioServer {
    public static void main(String[] args) throws Exception {
        AsynchronousServerSocketChannel server =
                AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8082));

        System.out.println("AIO server start...");

        CountDownLatch latch = new CountDownLatch(1);

        server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
            @Override
            public void completed(AsynchronousSocketChannel ch, Void att) {
                // 繼續(xù)接收下一個(gè)連接(非常關(guān)鍵,否則只接一次)
                server.accept(null, this);

                ByteBuffer buf = ByteBuffer.allocate(1024);
                ch.read(buf, buf, new CompletionHandler<Integer, ByteBuffer>() {
                    @Override
                    public void completed(Integer n, ByteBuffer b) {
                        try {
                            if (n <= 0) { ch.close(); return; }
                            b.flip();
                            ch.write(ByteBuffer.wrap("AIO reply: ".getBytes())).get();
                            ch.write(b).get();
                            ch.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    @Override
                    public void failed(Throwable exc, ByteBuffer b) {
                        try { ch.close(); } catch (Exception ignored) {}
                    }
                });
            }

            @Override
            public void failed(Throwable exc, Void att) {
                exc.printStackTrace();
                latch.countDown();
            }
        });

        latch.await(); // 防止主線程退出
    }
}

BIO、AIO、NIO小結(jié):

        BIO:同步阻塞,簡單但并發(fā)高會(huì)吃線程

        NIO:同步非阻塞,Selector 管理多連接,適合高并發(fā)

        AIO:異步非阻塞,回調(diào)/通知獲取結(jié)果,編程模型更異步

總結(jié)

到此這篇關(guān)于Java中BIO、NIO和AIO舉例總結(jié)的文章就介紹到這了,更多相關(guān)Java中BIO、NIO和AIO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java面試之SQL語句題經(jīng)典案例

    Java面試之SQL語句題經(jīng)典案例

    本文詳細(xì)討論了如何將行數(shù)據(jù)轉(zhuǎn)化為列數(shù)據(jù),并提供了多種SQL查詢練習(xí)題,包括查詢特定條件的學(xué)生信息、課程成績比較、學(xué)生成績排名等,文章還解釋了在SQL中使用Union、UnionAll和pivot的方法,以及如何處理復(fù)雜的SQL查詢問題,需要的朋友可以參考下
    2024-10-10
  • 淺析SpringBoot中的過濾器和攔截器

    淺析SpringBoot中的過濾器和攔截器

    過濾器和攔截器都是為了在請(qǐng)求到達(dá)目標(biāo)處理器(Servlet或Controller)之前或者之后插入自定義的處理邏輯,下面就跟隨小編來看看它們二者的區(qū)別和具體使用吧
    2024-03-03
  • java easyUI實(shí)現(xiàn)自定義網(wǎng)格視圖實(shí)例代碼

    java easyUI實(shí)現(xiàn)自定義網(wǎng)格視圖實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于java easyUI實(shí)現(xiàn)自定義網(wǎng)格視圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • Java并發(fā)編程之ReentrantLock實(shí)現(xiàn)原理及源碼剖析

    Java并發(fā)編程之ReentrantLock實(shí)現(xiàn)原理及源碼剖析

    ReentrantLock 是常用的鎖,相對(duì)于Synchronized ,lock鎖更人性化,閱讀性更強(qiáng),文中將會(huì)詳細(xì)的說明,請(qǐng)君往下閱讀
    2021-09-09
  • Java多線程提交按照時(shí)間順序獲取線程結(jié)果詳解流程

    Java多線程提交按照時(shí)間順序獲取線程結(jié)果詳解流程

    在工作中是否存在這樣的場(chǎng)景,多個(gè)線程提交執(zhí)行,你不想全部線程執(zhí)行結(jié)束了獲取結(jié)果,而是有線程完成返回結(jié)果就獲取消費(fèi)。本文提供該場(chǎng)景的工具類,可以直接用哦
    2021-11-11
  • 三級(jí)聯(lián)動(dòng)省市ajax的代碼

    三級(jí)聯(lián)動(dòng)省市ajax的代碼

    這篇文章主要為大家詳細(xì)介紹了ajax實(shí)現(xiàn)省市三級(jí)聯(lián)動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07
  • Java定義泛型方法實(shí)例分析

    Java定義泛型方法實(shí)例分析

    這篇文章主要介紹了Java定義泛型方法,結(jié)合實(shí)例形式分析了java定義泛型的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2019-07-07
  • Mybatis下的SQL注入漏洞原理及防護(hù)方法解析

    Mybatis下的SQL注入漏洞原理及防護(hù)方法解析

    SQL 注入是發(fā)生在 Web 程序中數(shù)據(jù)庫層的安全漏洞,是網(wǎng)站存在最多也是最簡單的漏洞,在實(shí)際項(xiàng)目中,即使使用了 Mybatis 框架,但仍然有可能因?yàn)榫幋a人員安全意識(shí)不足而導(dǎo)致 SQL 注入問題,這篇文章主要介紹了Mybatis下的SQL注入漏洞原理及防護(hù)方法?,需要的朋友可以參考下
    2022-11-11
  • Springboot接收?Form?表單數(shù)據(jù)的示例詳解

    Springboot接收?Form?表單數(shù)據(jù)的示例詳解

    這篇文章主要介紹了Springboot接收?Form?表單數(shù)據(jù)的實(shí)例代碼,本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • Spring的InitializingBean接口解析

    Spring的InitializingBean接口解析

    這篇文章主要介紹了Spring的InitializingBean接口解析,InitializingBean是spring為bean的初始化提供了一種新的方式,里面只有一個(gè)方法afterPropertiesSet,作用就是實(shí)現(xiàn)這個(gè)接口或者實(shí)現(xiàn)了繼承InitializingBean的方法的bean都要執(zhí)行這個(gè)方法,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

丹凤县| 南雄市| 光泽县| 年辖:市辖区| 洛川县| 钦州市| 增城市| 江源县| 开阳县| 介休市| 比如县| 牡丹江市| 巢湖市| 新竹市| 柘城县| 富蕴县| 中阳县| 萨迦县| 密云县| 吉隆县| 中卫市| 望城县| 阿克陶县| 高邮市| 周口市| 岚皋县| 中阳县| 洪泽县| 泌阳县| 咸宁市| 开江县| 会泽县| 平顺县| 景谷| 乾安县| 垦利县| 荣昌县| 合阳县| 同德县| 泽州县| 恭城|