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

Netty與NIO超詳細(xì)講解

 更新時(shí)間:2022年08月01日 15:05:10   作者:kaico2018  
Netty本質(zhì)上是一個(gè)NIO的框架,適用于服務(wù)器通訊相關(guān)的多種應(yīng)用場(chǎng)景。底層是NIO,NIO底層是Java?IO和網(wǎng)絡(luò)IO,再往下是TCP/IP協(xié)議,下面我們跟隨文章來(lái)詳細(xì)了解

Linux下的五種I/O模型

1)阻塞I/O(blocking I/O)

2)非阻塞I/O (nonblocking I/O)

3) I/O復(fù)用(select 和poll) (I/O multiplexing)

4)信號(hào)驅(qū)動(dòng)I/O (signal driven I/O (SIGIO))

5)異步I/O (asynchronous I/O (the POSIX aio_functions))

前面四種都是同步io、第五種是異步IO;

阻塞式:當(dāng)程序沒(méi)有獲取到數(shù)據(jù)的時(shí)候,整個(gè)應(yīng)用可能會(huì)產(chǎn)生阻塞,放棄了CPU執(zhí)行,無(wú)法去做其他事情。

非阻塞式:不管有沒(méi)有獲取到數(shù)據(jù),都必須立馬返回一個(gè)結(jié)果,如果沒(méi)有獲取到數(shù)據(jù)的情況下返回一個(gè)錯(cuò)誤標(biāo)記,根據(jù)錯(cuò)誤的標(biāo)記不斷輪詢。BIO屬于阻塞式的io操作??梢允褂枚嗑€程實(shí)現(xiàn)異步I0,同時(shí)處理多個(gè)請(qǐng)求。缺點(diǎn):非常消耗服務(wù)器資源CPU

阻塞IO的流程

BIO屬于阻塞式的io操作。

可以使用多線程實(shí)現(xiàn)異步IO,同時(shí)處理多個(gè)請(qǐng)求。缺點(diǎn):非常消耗服務(wù)器資源CPU

當(dāng)我們?cè)谡{(diào)用一個(gè)io函數(shù)的時(shí)候,如果沒(méi)有獲取到數(shù)據(jù)的情況下,那么就會(huì)一直等待;等待的過(guò)程中會(huì)導(dǎo)致整個(gè)應(yīng)用程序一直是一個(gè)阻塞的過(guò)程,無(wú)法去做其他的實(shí)現(xiàn)。

IO復(fù)用

IO復(fù)用機(jī)制:IO實(shí)際指的就是網(wǎng)絡(luò)的IO、多路也就是多個(gè)不同的tcp連接;復(fù)用也就是指使用同一個(gè)線程合并處理多個(gè)不同的IO操作,這樣的話可以減少CPU資源。

信號(hào)驅(qū)動(dòng)I/O

發(fā)出一個(gè)請(qǐng)求實(shí)現(xiàn)觀察監(jiān)聽(tīng),當(dāng)有數(shù)據(jù)的時(shí)候直接走我們異步回調(diào);

異步IO

異步io也就是發(fā)出請(qǐng)求數(shù)據(jù)之后,剩下的事情完全實(shí)現(xiàn)異步完成

同步與異步

站在多線程的角度總結(jié):

同步整個(gè)應(yīng)用代碼執(zhí)行順序是從上往下執(zhí)行 并且返回到結(jié)果;

異步:開(kāi)啟多個(gè)不同的分支實(shí)現(xiàn)并行執(zhí)行 每個(gè)線程互不影響;

站在web項(xiàng)目角度分析

默認(rèn)的情況Http請(qǐng)求就是一個(gè)同步形式實(shí)現(xiàn)調(diào)用 基于請(qǐng)求與響應(yīng),如果我們響應(yīng)非常耗時(shí)的話,會(huì)導(dǎo)致客戶端一直等待(用戶體驗(yàn)非常不好)

NIO

Java的nio是在Jdk1.4版本之后推出了一套新的io方案,這種io方案對(duì)原有io做了一次性能上的升級(jí)

NIO翻譯成英文 no blocking io 簡(jiǎn)稱為 nio 非阻塞io,不是new io。

比傳統(tǒng)的io支持了面向緩沖區(qū)、基于通道實(shí)現(xiàn)的io的方案。

BIO 與 NIO 區(qū)別:

Bio是一個(gè)阻塞式的io,它是西向與流傳輸也就是根據(jù)每個(gè)字節(jié)實(shí)現(xiàn)傳輸效率非常低,

而我們的nio是雨向與緩沖區(qū)的非阻塞邊.其中最大的亮點(diǎn):運(yùn)多路復(fù)用機(jī)制,

I0多路復(fù)用

多路實(shí)際上指的是多個(gè)不同的 tcp 連接。

復(fù)用:一個(gè)線程可以維護(hù)多個(gè)不同的io操作。

優(yōu)點(diǎn):占用cpu資源非常小、保證線程安全問(wèn)題。

IO 多路復(fù)用實(shí)現(xiàn)原理

使用一個(gè)Java案例來(lái)描述IO多路復(fù)用的思路:

public class SocketNioTcpServer {
    private static List<SocketChannel> listSocketChannel = new ArrayList<>();
    private static ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    public static void main(String[] args) {
        try {
            // 1.創(chuàng)建一個(gè)ServerSocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 2. 綁定地址
            ServerSocketChannel bind = serverSocketChannel.bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);
            while (true) {
                SocketChannel socketChannel = serverSocketChannel.accept();
                if (socketChannel != null) {
                    socketChannel.configureBlocking(false);
                    listSocketChannel.add(socketChannel);
                }
                for (SocketChannel scl : listSocketChannel) {
                    try {
                        int read = scl.read(byteBuffer);
                        if (read > 0) {
                            byteBuffer.flip();
                            Charset charset = Charset.forName("UTF-8");
                            String receiveText = charset.newDecoder().decode
                                    (byteBuffer.asReadOnlyBuffer()).toString();
                            System.out.println("receiveText:" + receiveText);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

NIO核心組件

通道(Channel)

通常我們nio所有的操作都是通過(guò)通道開(kāi)始的,所有的通道都會(huì)注冊(cè)到統(tǒng)一個(gè)選擇器(Selector)上實(shí)現(xiàn)管理,在通過(guò)選擇器將數(shù)據(jù)統(tǒng)一寫入到 buffer中。

緩沖區(qū)(Buffer)

Buffer本質(zhì)上就是一塊內(nèi)存區(qū),可以用來(lái)讀取數(shù)據(jù),也就先將數(shù)據(jù)寫入到緩沖區(qū)中、在統(tǒng)一的寫入到硬盤上。

選擇器(Selector)

Selector可以稱做為選擇器,也可以把它叫做多路復(fù)用器,可以在單線程的情況下可以去維護(hù)多個(gè)Channel,也可以去維護(hù)多個(gè)連接;

使用Java原生API實(shí)現(xiàn)NIO操作

public class NIOServer {
    /**
     * 創(chuàng)建一個(gè)選擇器
     */
    private Selector selector;
    public void initServer(int port) throws IOException {
        // 獲得一個(gè)ServerSocketChannel通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 設(shè)置通道為非阻塞
        serverSocketChannel.configureBlocking(false);
        // 將該通道對(duì)應(yīng)的ServerSocket綁定到port端口
        serverSocketChannel.bind(new InetSocketAddress(port));
        // 獲得一個(gè)通道管理器
        this.selector = Selector.open();
        // 將通道管理器和該通道綁定,并為該通道注冊(cè)SelectionKey.OP_ACCEPT事件,注冊(cè)該事件后,
        // 當(dāng)該事件到達(dá)時(shí),selector.select()會(huì)返回,如果該事件沒(méi)到達(dá)selector.select()會(huì)一直阻塞。
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }
    public void listen() throws IOException {
        System.out.println("服務(wù)端啟動(dòng)成功!");
        // 輪詢?cè)L問(wèn)selector
        while (true) {
            // 當(dāng)注冊(cè)的事件到達(dá)時(shí),方法返回;否則,該方法會(huì)一直阻塞
            int select = selector.select();
            if (select == 0) {
                continue;
            }
            // 獲得selector中選中的項(xiàng)的迭代器,選中的項(xiàng)為注冊(cè)的事件
            Iterator<SelectionKey> ite = this.selector.selectedKeys().iterator();
            while (ite.hasNext()) {
                SelectionKey key = (SelectionKey) ite.next();
                // 刪除已選的key,以防重復(fù)處理
                ite.remove();

                if (key.isAcceptable()) {// 客戶端請(qǐng)求連接事件
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    // 獲得和客戶端連接的通道
                    SocketChannel channel = server.accept();
                    // 設(shè)置成非阻塞
                    channel.configureBlocking(false);
                    // 在和客戶端連接成功之后,為了可以接收到客戶端的信息,需要給通道設(shè)置讀的權(quán)限。
                    channel.register(this.selector, SelectionKey.OP_READ);

                } else if (key.isReadable()) {// 獲得了可讀的事件
                    read(key);
                }

            }

        }
    }
    public void read(SelectionKey key) throws IOException {
        // 服務(wù)器可讀取消息:得到事件發(fā)生的Socket通道
        SocketChannel channel = (SocketChannel) key.channel();
        // 創(chuàng)建讀取的緩沖區(qū)
        ByteBuffer buffer = ByteBuffer.allocate(512);
        channel.read(buffer);
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("服務(wù)端收到信息:" + msg);
        ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes("utf-8"));
        channel.write(outBuffer);// 將消息回送給客戶端
    }
    public static void main(String[] args) throws IOException {
        NIOServer server = new NIOServer();
        server.initServer(8000);
        server.listen();
    }
}

Redis為什么支持高并發(fā)

Redis官方?jīng)]有windows版本redis,只有l(wèi)inux版本的reids。

Redis的底層是采用nio 多路io復(fù)用機(jī)制實(shí)現(xiàn)對(duì)多個(gè)不同的連接(tcp)實(shí)現(xiàn)io的復(fù)用;能夠非常好的支持高并發(fā),同時(shí)能夠先天性支持線程安全的問(wèn)題。為什么現(xiàn)場(chǎng)安全?因?yàn)槭褂靡粋€(gè)線程維護(hù)多個(gè)不同的io操作 原理使用nio的選擇器,將多個(gè)不同的Channel統(tǒng)一交給我們的selector(選擇器管理)。

但是nio的實(shí)現(xiàn)在不同的操作系統(tǒng)上存在差別:在我們windows操作系統(tǒng)上使用 select 實(shí)現(xiàn)輪訓(xùn)機(jī)制、在linux操作系統(tǒng)使用epoll

備注:windows操作系統(tǒng)是沒(méi)有epoll

在windows操作系統(tǒng)中使用select實(shí)現(xiàn)輪訓(xùn)機(jī)制時(shí)間復(fù)雜度是為 o(n),而且這種情況也會(huì)存在空輪訓(xùn)的情況,效率非常低、其次默認(rèn)對(duì)我們的輪訓(xùn)有一定限制,所以這樣的話很難支持上萬(wàn)tcp連接。

所以在這時(shí)候linux操作就出現(xiàn)epoll實(shí)現(xiàn)事件驅(qū)動(dòng)回調(diào)形式通知,不會(huì)存在空輪訓(xùn)的情況,只是對(duì)活躍的socket實(shí)現(xiàn)主動(dòng)回調(diào),這樣的性能有很大的提升 所以時(shí)間復(fù)雜度為是o(1)

注意:windows操作系統(tǒng)沒(méi)有epoll、只有l(wèi)inux操作系統(tǒng)有。

所以為什么Nginx、redis能夠支持非常高的并發(fā) 最終都是靠的linux版本的 io 多路復(fù)用機(jī)制epoll

到此這篇關(guān)于Netty與NIO超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Netty NIO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java由淺入深通關(guān)抽象類與接口上

    Java由淺入深通關(guān)抽象類與接口上

    在類中沒(méi)有包含足夠的信息來(lái)描繪一個(gè)具體的對(duì)象,這樣的類稱為抽象類,接口是Java中最重要的概念之一,它可以被理解為一種特殊的類,不同的是接口的成員沒(méi)有執(zhí)行體,是由全局常量和公共的抽象方法所組成,本文給大家介紹Java抽象類和接口,感興趣的朋友一起看看吧
    2022-04-04
  • Java Mybatis框架Dao層的實(shí)現(xiàn)與映射文件以及核心配置文件詳解分析

    Java Mybatis框架Dao層的實(shí)現(xiàn)與映射文件以及核心配置文件詳解分析

    MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過(guò)簡(jiǎn)單的 XML 或注解來(lái)配置和映射原始類型、接口和 Java POJO為數(shù)據(jù)庫(kù)中的記錄
    2021-10-10
  • 一文總結(jié) Shiro 實(shí)戰(zhàn)教程

    一文總結(jié) Shiro 實(shí)戰(zhàn)教程

    shiro是apache的一個(gè)開(kāi)源框架,是一個(gè)權(quán)限管理的框架,實(shí)現(xiàn) 用戶認(rèn)證、用戶授權(quán),這篇文章詳細(xì)總結(jié)了shiro用法,感興趣的同學(xué)可以參考閱讀
    2023-04-04
  • 深入Java不可變類型的詳解

    深入Java不可變類型的詳解

    本篇文章是Java中的不可變類型進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Java IO流常用字節(jié)字符流原理解析

    Java IO流常用字節(jié)字符流原理解析

    這篇文章主要介紹了Java IO流常用字節(jié)字符流原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java中正則表達(dá)式的使用和詳解(上)

    Java中正則表達(dá)式的使用和詳解(上)

    這篇文章主要介紹了Java中正則表達(dá)式的使用和詳解,包括匹配驗(yàn)證驗(yàn)證email是否正確,在字符串中查詢字符或者字符串的代碼實(shí)例,需要的朋友可以參考下
    2017-04-04
  • java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決

    java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決

    這篇文章主要介紹了java 使用ImageIO.writer從BufferedImage生成jpeg圖像遇到問(wèn)題總結(jié)及解決的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • SpringBoot中使用Zookeeper實(shí)現(xiàn)分布式鎖的案例

    SpringBoot中使用Zookeeper實(shí)現(xiàn)分布式鎖的案例

    本文主要介紹了SpringBoot中使用Zookeeper實(shí)現(xiàn)分布式鎖的案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • 在Struts2中如何將父類屬性序列化為JSON格式的解決方法

    在Struts2中如何將父類屬性序列化為JSON格式的解決方法

    本篇文章,小編將為大家介紹關(guān)于在Struts2中如何將父類屬性序列化為JSON格式的解決方法,有需要的朋友可以參考一下
    2013-04-04
  • Spring Data JPA帶條件分頁(yè)查詢實(shí)現(xiàn)原理

    Spring Data JPA帶條件分頁(yè)查詢實(shí)現(xiàn)原理

    這篇文章主要介紹了Spring Data JPA帶條件分頁(yè)查詢實(shí)現(xiàn)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評(píng)論

舟曲县| 鸡泽县| 延津县| 中江县| 招远市| 阜南县| 神木县| 岳阳市| 大厂| 泸溪县| 石柱| 巩义市| 华亭县| 西林县| 敦煌市| 阿拉善左旗| 繁峙县| 茂名市| 道孚县| 阿图什市| 江安县| 石林| 敦化市| 冕宁县| 南投县| 新密市| 长葛市| 鹤山市| 西乌珠穆沁旗| 河西区| 交口县| 启东市| 呼玛县| 成武县| 沙洋县| 成都市| 宜宾县| 临高县| 宿松县| 北票市| 岳普湖县|