欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你搞懂什么是BIO

 更新時(shí)間:2023年06月29日 11:42:39   作者:寫bug的黑貓  
BIO英文全名是 blocking IO,也叫做 阻塞IO,是最容易理解、最容易實(shí)現(xiàn)的IO工作方式,本文就來(lái)通過(guò)一些簡(jiǎn)單的示例為大家講講什么是BIO吧

BIO

BIO英文全名是 blocking IO,也叫做 阻塞IO,是最容易理解、最容易實(shí)現(xiàn)的IO工作方式。

1.1、什么是阻塞IO(BIO)

當(dāng)我們?cè)谡務(wù)撟枞鸌O(Blocking IO)時(shí),我們指的是一種輸入輸出方式,其中線程正在進(jìn)行IO操作時(shí)會(huì)被阻塞(即暫停運(yùn)行),直到IO 操作完成。這種阻塞是同步的,也就是說(shuō)線程會(huì)等待IO操作完成后再繼續(xù)執(zhí)行后續(xù)的任務(wù)。

在阻塞IO中,當(dāng)一個(gè)線程調(diào)用IO操作(如讀取或?qū)懭霐?shù)據(jù))時(shí),如果沒(méi)有數(shù)據(jù)可用或無(wú)法立即完成IO操作,線程會(huì)被掛起,直到滿足操作條件。這種掛起意味著線程無(wú)法執(zhí)行其他任務(wù),因?yàn)樗恢钡却齀O操作完成。

舉個(gè)例子說(shuō)明,假設(shè)一個(gè)線程負(fù)責(zé)從網(wǎng)絡(luò)套接字讀取數(shù)據(jù),Socket就是網(wǎng)絡(luò)套接字。當(dāng)線程調(diào)用讀取數(shù)據(jù)的方法時(shí),如果沒(méi)有數(shù)據(jù)可用,線程將被阻塞,直到有數(shù)據(jù)可讀為止。在此期間,線程無(wú)法執(zhí)行其他任務(wù),他會(huì)一直等待直到數(shù)據(jù)到達(dá)或IO操作超時(shí)。

阻塞IO的特點(diǎn)是簡(jiǎn)單易懂,但也存在一些問(wèn)題。其他一個(gè)問(wèn)題是當(dāng)有多個(gè)IO操作需要處理時(shí),每個(gè)操作都會(huì)阻塞對(duì)應(yīng)的線程,導(dǎo)致線程的浪費(fèi)。在高并發(fā)或大規(guī)模的應(yīng)用程序中,這可能會(huì)導(dǎo)致性能的下降,因?yàn)榫€程的創(chuàng)建和上下文切換會(huì)帶來(lái)額外的開(kāi)銷。

為了解決阻塞IO的性能問(wèn)題,Java引入了非阻塞IO(Non-blocking IO)模型,例如NIO(New IO)和NIO.2。這些模型使用了事件驅(qū)動(dòng)的方式,通過(guò)單個(gè)線程處理多個(gè)IO操作。當(dāng)一個(gè)IO操作無(wú)法立即完成時(shí),線程不會(huì)被阻塞,而是繼續(xù)執(zhí)行其他任務(wù),等待IO操作完成后再處理。這種方式能更有效地利用系統(tǒng)資源,并提高并發(fā)處理能力。

綜上所述,阻塞IO是一種簡(jiǎn)單易懂的IO操作方式,但在高并發(fā)或大規(guī)模應(yīng)用程序中可能存在性能問(wèn)題。了解阻塞IO的概念可以幫助我們理解其他IO模型的工作原理和優(yōu)勢(shì)。

1.2、BIO工作原理

當(dāng)一個(gè)客戶端請(qǐng)求到達(dá)服務(wù)器時(shí),服務(wù)器會(huì)為該請(qǐng)求創(chuàng)建一個(gè)新的線程。這個(gè)線程將負(fù)責(zé)處理該請(qǐng)求的所有IO操作,包括讀取請(qǐng)求數(shù)據(jù)、處理請(qǐng)求、發(fā)送響應(yīng)等。這種一對(duì)一的線程模型在簡(jiǎn)單的應(yīng)用場(chǎng)景下可能是可行的,但當(dāng)并發(fā)請(qǐng)求增加時(shí),線程的數(shù)量也會(huì)相應(yīng)增加。

大量線程的創(chuàng)建和管理開(kāi)銷較大,會(huì)消耗大量的系統(tǒng)資源,包括內(nèi)存和CPU。每個(gè)線程都需要占用一定的內(nèi)存空間,并且線程之間的切換也需要消耗CPU資源。如果并發(fā)請(qǐng)求非常高,線程的數(shù)量可能會(huì)過(guò)多,導(dǎo)致系統(tǒng)資源不足,甚至引發(fā)性能下降、系統(tǒng)崩潰等問(wèn)題。

BIO的優(yōu)點(diǎn)是通俗易懂,適用于一些處理少量應(yīng)發(fā)請(qǐng)求的簡(jiǎn)單服務(wù)器,比如:?jiǎn)尉€程服務(wù)器、簡(jiǎn)單的客戶端-服務(wù)器通信等。對(duì)于高并發(fā)、大規(guī)模的網(wǎng)絡(luò)應(yīng)該程序,BIO模型可能無(wú)法滿足要求,這會(huì)使得線程創(chuàng)建和管理開(kāi)銷太大。

1.3、BIO服務(wù)器

當(dāng)談到編寫一個(gè)BIO(Blocking I/O)程序時(shí),我們可以創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器,它能夠接受客戶端連接請(qǐng)求并處理這些請(qǐng)求。下面是一個(gè)使用java socket編寫的BIO服務(wù)器簡(jiǎn)單示例:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BioServer {
    public static void main(String[] args) {
        int port = 8080; // 服務(wù)器監(jiān)聽(tīng)的端口號(hào)
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("服務(wù)器啟動(dòng),監(jiān)聽(tīng)端口:" + port);
            while (true) {
                // 等待客戶端連接
                Socket socket = serverSocket.accept();
                System.out.println("客戶端連接成功,地址:" + socket.getInetAddress() + ":" + socket.getPort());
                // 創(chuàng)建線程處理客戶端請(qǐng)求
                new Thread(() -> {
                    try {
                        // 獲取輸入流和輸出流
                        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintWriter writer = new PrintWriter(socket.getOutputStream());
                        // 讀取客戶端發(fā)送的數(shù)據(jù)
                        String request = reader.readLine();
                        System.out.println("接收到客戶端數(shù)據(jù):" + request);
                        // 處理請(qǐng)求并返回響應(yīng)
                        String response = "Hello, client!";
                        writer.println(response);
                        writer.flush();
                        System.out.println("發(fā)送響應(yīng)給客戶端:" + response);
                        // 關(guān)閉連接
                        socket.close();
                        System.out.println("客戶端連接關(guān)閉");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

這個(gè)示例程序創(chuàng)建了一個(gè)ServerSocket來(lái)監(jiān)聽(tīng)指定端口(這里使用8080)。在主循環(huán)中,通過(guò)調(diào)用accept()方法等待客戶端的連接請(qǐng)求,沒(méi)有連接的時(shí)候,程序會(huì)一直阻塞在這里,直到收到客戶端連接請(qǐng)求。一旦客戶端連接成功,程序會(huì)創(chuàng)建一個(gè)新的線程來(lái)處理該客戶端的請(qǐng)求。

在處理線程中,我們獲取與客戶端連接的輸入流和輸出流,使用BufferedReader來(lái)讀取客戶端發(fā)送的數(shù)據(jù),并使用PrintWriter來(lái)進(jìn)行客戶端發(fā)送響應(yīng)。這里處理邏輯非常簡(jiǎn)單,及僅僅返回一個(gè)固定的字符作為響應(yīng)。

當(dāng)請(qǐng)求處理結(jié)束后,關(guān)閉與客戶端的連接,并繼續(xù)等待下一個(gè)客戶端的連接。

需要注意,這個(gè)示例程序是單線程的。當(dāng)有新的客戶端連接時(shí),都會(huì)創(chuàng)建一個(gè)新的線程來(lái)處理請(qǐng)求。這種方式僅適用于簡(jiǎn)單的應(yīng)用場(chǎng)景,在高并發(fā)下,會(huì)創(chuàng)建大量的線程,導(dǎo)致性能下降。

1.4、BIO客戶端

如果想發(fā)送消息到上面的BIO服務(wù)器,我們可以使用一個(gè)簡(jiǎn)單的Socket客戶端來(lái)連接服務(wù)器并發(fā)送請(qǐng)求。以下是一個(gè)示例代碼:

import java.io.*;
import java.net.Socket;
public class BioClient {
    public static void main(String[] args) {
        String serverAddress = "localhost"; // 服務(wù)器地址
        int serverPort = 8080; // 服務(wù)器端口號(hào)
        try {
            // 連接服務(wù)器
            Socket socket = new Socket(serverAddress, serverPort);
            System.out.println("連接服務(wù)器成功");
            // 獲取輸入流和輸出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            // 發(fā)送請(qǐng)求
            String request = "Hello, server!";
            writer.println(request);
            writer.flush();
            System.out.println("發(fā)送請(qǐng)求給服務(wù)器:" + request);
            // 接收響應(yīng)
            String response = reader.readLine();
            System.out.println("接收到服務(wù)器響應(yīng):" + response);
            // 關(guān)閉連接
            socket.close();
            System.out.println("連接關(guān)閉");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

在這個(gè)示例程序中,BIO客戶端與服務(wù)器的通信過(guò)程如下:

  • 創(chuàng)建一個(gè)Socket對(duì)象,指定服務(wù)器地址和端口號(hào)。
  • 通過(guò)調(diào)用Socket對(duì)象的getInputStream()方法和getOutputStream()方法,分別獲取與服務(wù)器連接的輸入流和輸出流。輸入流用于接收服務(wù)器的響應(yīng),輸出流用于向服務(wù)器發(fā)送請(qǐng)求。
  • 構(gòu)造一個(gè)請(qǐng)求消息,例如Hello, server!。
  • 使用輸出流的println()方法將請(qǐng)求消息發(fā)送給服務(wù)器,并調(diào)用flush()方法確保消息被立即發(fā)送到服務(wù)器。
  • 使用輸入流的readLine()方法來(lái)讀取服務(wù)器發(fā)送的響應(yīng)消息。
  • 打印接收到的服務(wù)器響應(yīng)消息。
  • 關(guān)閉與服務(wù)器的連接,調(diào)用Socket對(duì)象的close()方法。

你可以在該示例程序中修改請(qǐng)求消息和服務(wù)器地址、端口號(hào),以適應(yīng)你的實(shí)際情況。

運(yùn)行實(shí)例

先啟動(dòng)服務(wù)器,進(jìn)行端口監(jiān)聽(tīng),再啟動(dòng)客戶端,連接到指定服務(wù)器地址的端口

#BioServer輸出臺(tái)顯示

服務(wù)器啟動(dòng),監(jiān)聽(tīng)端口:8080
客戶端連接成功,地址:/127.0.0.1:60038
接收到客戶端數(shù)據(jù):Hello, server!
發(fā)送響應(yīng)給客戶端:Hello, client!
客戶端連接關(guān)閉

#BioClient輸出臺(tái)顯示

連接服務(wù)器成功
發(fā)送請(qǐng)求給服務(wù)器:Hello, server!
接收到服務(wù)器響應(yīng):Hello, client!
連接關(guān)閉

結(jié)尾

盡管阻塞IO模型簡(jiǎn)單易懂,但在高并發(fā)或大規(guī)模的網(wǎng)絡(luò)應(yīng)用程序中,使用該模型可能會(huì)遇到線程創(chuàng)建和管理開(kāi)銷過(guò)大的問(wèn)題。因此,在需要高并發(fā)處理的場(chǎng)景下,阻塞IO模型并不是最理想的選擇。

為了解決這個(gè)問(wèn)題,可以考慮使用其他IO模型,如非阻塞IO(NIO)或基于NIO的框架(如Netty)。

非阻塞IO模型通過(guò)使用非阻塞的IO操作和事件輪詢機(jī)制,允許程序在等待IO操作完成的同時(shí)繼續(xù)執(zhí)行其他任務(wù),從而提高了系統(tǒng)的并發(fā)能力。而基于NIO的框架則提供了更高級(jí)別的抽象和更靈活的IO操作方式,例如使用選擇器(Selector)來(lái)管理多個(gè)IO通道,實(shí)現(xiàn)單線程處理多個(gè)IO連接。

這些模型可以使用較少的線程處理多個(gè)請(qǐng)求,并且能更好地利用系統(tǒng)資源,提高并發(fā)處理能力。

非阻塞IO和基于NIO的框架具有以下優(yōu)勢(shì):

  • 更高的并發(fā)性能:不像阻塞IO模型那樣頻繁地創(chuàng)建和管理線程,,非阻塞IO和基于NIO的框架能夠通過(guò)一個(gè)線程處理多個(gè)IO連接,減少了線程創(chuàng)建和管理的開(kāi)銷,從而提高了系統(tǒng)的并發(fā)性能。
  • 更靈活的IO操作方式:非阻塞IO和基于NIO的框架提供了更靈活的IO操作方式,例如事件驅(qū)動(dòng)的編程模型和選擇器機(jī)制,使得程序能夠更高效地管理和處理多個(gè)IO連接。
  • 資源利用率更高:更加節(jié)約資源,由于非阻塞IO和基于NIO的框架使用了較少的線程,可以更有效地利用系統(tǒng)資源,避免了線程創(chuàng)建和上下文切換的開(kāi)銷。

在選擇適合的IO模型時(shí),需要根據(jù)具體的應(yīng)用場(chǎng)景和性能需求來(lái)權(quán)衡各種模型的優(yōu)劣。阻塞IO模型適用于簡(jiǎn)單的、低并發(fā)的應(yīng)用場(chǎng)景,而非阻塞IO和基于NIO的框架則更適合需要處理大量并發(fā)連接的高性能應(yīng)用。

到此這篇關(guān)于一文帶你搞懂什么是BIO的文章就介紹到這了,更多相關(guān)Java BIO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringSecurity自動(dòng)登錄流程與實(shí)現(xiàn)詳解

    SpringSecurity自動(dòng)登錄流程與實(shí)現(xiàn)詳解

    這篇文章主要介紹了SpringSecurity自動(dòng)登錄流程與實(shí)現(xiàn)詳解,所謂的自動(dòng)登錄是在訪問(wèn)鏈接時(shí)瀏覽器自動(dòng)攜帶上了Cookie中的Token交給后端校驗(yàn),如果刪掉了Cookie或者過(guò)期了同樣是需要再次驗(yàn)證的,需要的朋友可以參考下
    2024-01-01
  • Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼

    Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼

    這篇文章主要介紹了Springboot+AOP實(shí)現(xiàn)返回?cái)?shù)據(jù)提示語(yǔ)國(guó)際化的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • Java中BeanMap的使用方法

    Java中BeanMap的使用方法

    這篇文章主要介紹了Java中BeanMap的使用方法,BeanMap來(lái)源于spring 框架,可以將一般的類轉(zhuǎn)為 Map 結(jié)構(gòu)存儲(chǔ),基于Map的JavaBean視圖,默認(rèn)的鍵集是所有屬性名稱的聯(lián)合,需要的朋友可以參考下
    2024-01-01
  • java解壓zip文件示例

    java解壓zip文件示例

    這篇文章主要介紹了java解壓zip文件示例,在獲得一個(gè)以Zip格式壓縮的文件之后,需要將其進(jìn)行解壓縮,還原成壓縮前的文件,下面是代碼示例
    2014-03-03
  • mybatis?plus配置自動(dòng)create_time和update_time方式

    mybatis?plus配置自動(dòng)create_time和update_time方式

    在處理數(shù)據(jù)時(shí),注意時(shí)間類型的轉(zhuǎn)換非常重要,不同編程環(huán)境和數(shù)據(jù)庫(kù)對(duì)時(shí)間數(shù)據(jù)的處理方式各異,因此在數(shù)據(jù)遷移或日常處理中需謹(jǐn)慎處理時(shí)間格式,個(gè)人經(jīng)驗(yàn)表明,了解常用的時(shí)間轉(zhuǎn)換函數(shù)和方法能有效避免錯(cuò)誤,提高工作效率,希望這些經(jīng)驗(yàn)?zāi)転榇蠹規(guī)?lái)幫助
    2024-09-09
  • springMVC圖片上傳的處理方式詳解

    springMVC圖片上傳的處理方式詳解

    這篇文章主要為大家詳細(xì)介紹了springMVC圖片上傳的處理方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • SpringBoot獲取Request對(duì)象的常見(jiàn)方法

    SpringBoot獲取Request對(duì)象的常見(jiàn)方法

    HttpServletRequest 簡(jiǎn)稱 Request,它是一個(gè) Servlet API 提供的對(duì)象,用于獲取客戶端發(fā)起的 HTTP 請(qǐng)求信息,那么在SpringBoot中,獲取 Request對(duì)象的方法有哪些呢,本文小編將給大家講講SpringBoot獲取Request對(duì)象的常見(jiàn)方法
    2023-08-08
  • Sentinel中三種流控模式的使用詳解

    Sentinel中三種流控模式的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Sentinel中三種流控模式(預(yù)熱模式,排隊(duì)等待模式和熱點(diǎn)規(guī)則)的使用,文中的示例代碼講解詳細(xì),感興趣的可以了解下
    2023-08-08
  • 詳解Java策略模式

    詳解Java策略模式

    今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著Java策略模式展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)管理的示例代碼

    Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)管理的示例代碼

    最近在做spring boot項(xiàng)目開(kāi)發(fā)中,由于使用@EnableScheduling注解和@Scheduled注解來(lái)實(shí)現(xiàn)的定時(shí)任務(wù),只能靜態(tài)的創(chuàng)建定時(shí)任務(wù),不能動(dòng)態(tài)修改、添加、刪除、啟/停任務(wù),下面通過(guò)本文給大家介紹Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)管理的方法,感興趣的朋友跟隨小編一起看看吧
    2023-07-07

最新評(píng)論