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

Java中的同步非阻塞IO模型詳解

 更新時間:2024年01月23日 10:54:37   作者:北漂碼農(nóng)有話說  
這篇文章主要介紹了Java中的同步非阻塞IO模型詳解,同步非阻塞IO模型,我們能夠知道,用戶線程一直發(fā)送請求,內(nèi)核一直都能都夠返回 ,直到內(nèi)核完成準備數(shù)據(jù)、數(shù)據(jù)拷貝的工作,并且返回成功的指示,在此過程中用戶線程不是阻塞的狀態(tài),需要的朋友可以參考下

介紹

IO模型中的,同步非阻塞IO模型,我們能夠知道,用戶線程一直發(fā)送請求,內(nèi)核一直都能都夠返回 ,直到內(nèi)核完成準備數(shù)據(jù)、數(shù)據(jù)拷貝的工作。

并且返回成功的指示。在此過程中用戶線程不是阻塞的狀態(tài)

實現(xiàn)

使用java來實現(xiàn)同步非阻塞IO模型,即我們所說的NIO的模型

客戶端實現(xiàn)

/**
 * @author:triumphxx
 * @Date:2021/11/12
 * @Time:11:03 下午
 * @微信公眾號:北漂碼農(nóng)有話說
 * @網(wǎng)站:http://blog.triumphxx.com.cn
 * @GitHub https://github.com/triumphxx
 * @Desc: NIO編程模型客戶端
 **/
public class NIOClient {
    // 通道管理器(Selector)
    private static Selector selector;
    public static void main(String[] args) throws IOException {
        // 創(chuàng)建通道管理器(Selector)
        selector = Selector.open();
        // 創(chuàng)建通道SocketChannel
        SocketChannel channel = SocketChannel.open();
        // 將通道設置為非阻塞
        channel.configureBlocking(false);
        // 客戶端連接服務器,其實方法執(zhí)行并沒有實現(xiàn)連接,需要在handleConnect方法中調(diào)channel.finishConnect()才能完成連接
        channel.connect(new InetSocketAddress("localhost", 9090));
        /**
         * 將通道(Channel)注冊到通道管理器(Selector),并為該通道注冊selectionKey.OP_CONNECT
         * 注冊該事件后,當事件到達的時候,selector.select()會返回,
         * 如果事件沒有到達selector.select()會一直阻塞。
         */
        channel.register(selector, SelectionKey.OP_CONNECT);
        // 循環(huán)處理
        while (true) {
            /*
             * 選擇一組可以進行I/O操作的事件,放在selector中,客戶端的該方法不會阻塞,
             * selector的wakeup方法被調(diào)用,方法返回,而對于客戶端來說,通道一直是被選中的
             * 這里和服務端的方法不一樣,查看api注釋可以知道,當至少一個通道被選中時。
             */
            selector.select();
            // 獲取監(jiān)聽事件
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            // 迭代處理
            while (iterator.hasNext()) {
                // 獲取事件
                SelectionKey key = iterator.next();
                // 移除事件,避免重復處理
                iterator.remove();
                // 檢查是否是一個就緒的已經(jīng)連接服務端成功事件
                if (key.isConnectable()) {
                    handleConnect(key);
                } else if (key.isReadable()) {// 檢查套接字是否已經(jīng)準備好讀數(shù)據(jù)
                    handleRead(key);
                }
            }
        }
    }
    /**
     * 處理客戶端連接服務端成功事件
     */
    private static void handleConnect(SelectionKey key) throws IOException {
        // 獲取與服務端建立連接的通道
        SocketChannel channel = (SocketChannel) key.channel();
        if (channel.isConnectionPending()) {
            // channel.finishConnect()才能完成連接
            channel.finishConnect();
        }
        channel.configureBlocking(false);
        // 數(shù)據(jù)寫入通道
        String msg = "Hello Server!";
        channel.write(ByteBuffer.wrap(msg.getBytes()));
        // 通道注冊到選擇器,并且這個通道只對讀事件感興趣
        channel.register(selector, SelectionKey.OP_READ);
    }
    /**
     * 監(jiān)聽到讀事件,讀取客戶端發(fā)送過來的消息
     */
    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        //開辟堆內(nèi)緩沖區(qū)
        ByteBuffer buffer = ByteBuffer.allocate(128);
        // 從通道讀取數(shù)據(jù)到緩沖區(qū)
        channel.read(buffer);
        // 輸出服務端響應發(fā)送過來的消息
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("服務端發(fā)來的消息:" + msg);
    }
}

由客戶端的代碼可以知道:首先我們將 select 打開,然后創(chuàng)建通道、將通道設置為非阻塞、創(chuàng)建連接、完成注冊 等待監(jiān)聽、處理事件,詳細的每一行代碼的意思,都已經(jīng)進展標注??创a即可。

服務端實現(xiàn)

**
 * @author:triumphxx
 * @Date:2021/11/12
 * @Time:11:03 下午
 * @微信公眾號:北漂碼農(nóng)有話說
 * @網(wǎng)站:http://blog.triumphxx.com.cn
 * @GitHub https://github.com/triumphxx
 * @Desc: NIO編程模型服務端
 **/
public class NIOServer {
    // 通道管理器(Selector)
    private static Selector selector;
    public static void main(String[] args) throws IOException {
        // 創(chuàng)建通道管理器(Selector)
        selector = Selector.open();
        // 創(chuàng)建通道ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 將通道設置為非阻塞
        serverSocketChannel.configureBlocking(false);
        // 將ServerSocketChannel對應的ServerSocket綁定到指定端口(port)
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(new InetSocketAddress(9090));
        /**
         * 將通道(Channel)注冊到通道管理器(Selector),并為該通道注冊selectionKey.OP_ACCEPT事件
         * 注冊該事件后,當事件到達的時候,selector.select()會返回,
         * 如果事件沒有到達selector.select()會一直阻塞。
         */
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        // 循環(huán)處理
        while (true) {
            // 當注冊事件到達時,方法返回,否則該方法會一直阻塞
            selector.select();
            // 獲取監(jiān)聽事件
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            // 迭代處理
            while (iterator.hasNext()) {
                // 獲取事件
                SelectionKey key = iterator.next();
                // 移除事件,避免重復處理
                iterator.remove();
                // 檢查是否是一個就緒的可以被接受的客戶端請求連接
                if (key.isAcceptable()) {
                    handleAccept(key);
                } else if (key.isReadable()) {// 檢查套接字是否已經(jīng)準備好讀數(shù)據(jù)
                    handleRead(key);
                }
            }
        }
    }
    /**
     * 處理客戶端連接成功事件
     */
    private static void handleAccept(SelectionKey key) throws IOException {
        // 獲取客戶端連接通道
        ServerSocketChannel server = (ServerSocketChannel) key.channel();
        SocketChannel socketChannel = server.accept();
        socketChannel.configureBlocking(false);
        // 信息通過通道發(fā)送給客戶端
        String msg = "Hello Client!";
        socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
        // 給通道設置讀事件,客戶端監(jiān)聽到讀事件后,進行讀取操作
        socketChannel.register(selector, SelectionKey.OP_READ);
    }
    /**
     * 監(jiān)聽到讀事件,讀取客戶端發(fā)送過來的消息
     */
    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        // 從通道讀取數(shù)據(jù)到緩沖區(qū)
        ByteBuffer buffer = ByteBuffer.allocate(128);
        channel.read(buffer);
        // 輸出客戶端發(fā)送過來的消息
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("server received msg from client:" + msg);
    }
}

有服務端的代碼可以知道:首先我們將 select 打開,然后創(chuàng)建通道、將通道設置為非阻塞、創(chuàng)建連接、完成注冊 等待監(jiān)聽、處理事件,詳細的每一行代碼的意思,都已經(jīng)進展標注??创a即可。

優(yōu)點及缺點

優(yōu)點:可靠性高,吞吐量比較高、非阻塞

缺點:編程模型做復雜

適用場景

適用于連接比較多且連接比較短的場景。

比如聊天室!

到此這篇關于Java中的同步非阻塞IO模型詳解的文章就介紹到這了,更多相關同步非阻塞IO模型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java基礎詳解之數(shù)據(jù)類型知識點總結(jié)

    java基礎詳解之數(shù)據(jù)類型知識點總結(jié)

    這篇文章主要介紹了java基礎詳解之數(shù)據(jù)類型知識點總結(jié),文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有很大的幫助,需要的朋友可以參考下
    2021-04-04
  • java多態(tài)的向上轉(zhuǎn)型的概念及實例分析

    java多態(tài)的向上轉(zhuǎn)型的概念及實例分析

    在本篇內(nèi)容里小編給大家整理的是一篇關于java多態(tài)的向上轉(zhuǎn)型的概念及實例分析,對此有興趣的朋友們可以跟著學習下。
    2021-05-05
  • elasticsearch中term與match的區(qū)別講解

    elasticsearch中term與match的區(qū)別講解

    今天小編就為大家分享一篇關于elasticsearch中term與match的區(qū)別講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • elasticsearch節(jié)點間通信的基礎transport啟動過程

    elasticsearch節(jié)點間通信的基礎transport啟動過程

    這篇文章主要為大家介紹了elasticsearch節(jié)點間通信的基礎transport啟動過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • 關于Mybatis與JPA的優(yōu)缺點說明

    關于Mybatis與JPA的優(yōu)缺點說明

    這篇文章主要介紹了關于Mybatis與JPA的優(yōu)缺點說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java tomcat手動配置servlet詳解

    Java tomcat手動配置servlet詳解

    這篇文章主要為大家介紹了tomcat手動配置servlet,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • java設計優(yōu)化之單例模式

    java設計優(yōu)化之單例模式

    這篇文章主要為大家詳細介紹了java設計優(yōu)化中的單例模式,深入學習java單例模式,感興趣的朋友可以參考一下
    2016-03-03
  • Spring?BeanFactory容器的構建和使用示例詳解

    Spring?BeanFactory容器的構建和使用示例詳解

    BeanFactory是Spring框架中的一部分,它提供了IoC(控制反轉(zhuǎn))的實現(xiàn)機制,下面小編就來和大家簡單聊聊BeanFactory容器的構建和使用示例吧
    2023-07-07
  • Spring中@Validated和@Valid區(qū)別淺析

    Spring中@Validated和@Valid區(qū)別淺析

    @Valid是javax.validation里的,?@Validated是@Valid?的一次封裝,是Spring提供的校驗機制使用,下面這篇文章主要給大家介紹了關于Spring中@Validated和@Valid區(qū)別的相關資料,需要的朋友可以參考下
    2022-04-04
  • Java探索之Thread+IO文件的加密解密代碼實例

    Java探索之Thread+IO文件的加密解密代碼實例

    這篇文章主要介紹了Java探索之Thread+IO文件的加密解密代碼實例,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10

最新評論