国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

NIO核心三:Selector

這篇具有很好參考價(jià)值的文章主要介紹了NIO核心三:Selector。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、基本概念

選擇器提供一種選擇執(zhí)行已經(jīng)就緒的任務(wù)的能力。selector選擇器可以讓單線程處理多個(gè)通道。如果程序打開了多個(gè)連接通道,每個(gè)連接的流量都比較低,可以使用Selector對通道進(jìn)行管理。
NIO核心三:Selector,java AIO BIO NIO,nio,java

二、如何創(chuàng)建選擇器

1.創(chuàng)建Selector

Selector selector = Selector.open();

2.必須將通道設(shè)置為非阻塞模式才能注冊到選擇器上

Channel.configureBlocking(false);

3.把通道注冊到選擇器上,會返回一個(gè)選擇鍵

SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);

SelectionKey的操作有:

  • SelectionKey.OP_CONNECT,指某個(gè)通道連接到服務(wù)器
  • SelectionKey.OP_ACCEPT,只有ServerSocketChannel有這個(gè)事件,查看是否有新的連接
  • SelectionKey.OP_READ,是否有可讀的通道就緒
  • SelectionKey.OP_WRITE,寫數(shù)據(jù)的通道是否就緒

注冊完成后,可以調(diào)用select()方法輪詢是否有就緒的通道

int count = selector.select();

select()方法,返回就緒的通道數(shù)量

三、服務(wù)器端模板

//服務(wù)器端模板代碼
public static void Server_Standard_Code_template() {
    try {
        ServerSocketChannel ssc=ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress("localhost",80));
        //只有設(shè)置為非阻塞才能注冊到選擇器中
        ssc.configureBlocking(false);
        //創(chuàng)建一個(gè)選擇器
        Selector selector = Selector.open();
        //通道注冊進(jìn)選擇器中---監(jiān)聽客戶端連接事件
        ssc.register(selector, SelectionKey.OP_ACCEPT);

        while(true){
            //獲取以及就緒的通道數(shù)量
            int select = selector.select();
            //沒有通道就緒
            if(select==0)
            {
                continue;
            }
            //獲取已經(jīng)就緒的
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext())
            {
                SelectionKey selectionKey = iterator.next();
                //客戶端連接請求事件
                if(selectionKey.isAcceptable())
                {
                    //接收連接
                }else if(selectionKey.isReadable())
                {
                    //讀取數(shù)據(jù)
                }
                else if(selectionKey.isWritable())
                {
                    //寫數(shù)據(jù)
                }
                //移除
                iterator.remove();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

四、NIO通訊實(shí)例

服務(wù)器端

public class NIOServer {
    //通道管理器
    private Selector selector;

    /**
     * 獲取一個(gè)ServerSocket通道,并對該通道做一些初始化工作
     * @param port 端口號
     * @throws IOException
     */
    public void initServer(int port) throws IOException {
        //獲取一個(gè)ServerSocket通道
        ServerSocketChannel socketChannel = ServerSocketChannel.open();
        //設(shè)置通道為非阻塞
        socketChannel.configureBlocking(false);
        //將通道對應(yīng)的ServerSocket綁定到port端口
        socketChannel.socket().bind(new InetSocketAddress(port));
        //獲取一個(gè)通道管理器
        this.selector = Selector.open();
        /**
         * 將通道管理器和該通道綁定,并為該通道注冊SelectionKey.OP_ACCEPT事件
         * 注冊該事件后,當(dāng)該事件到達(dá)時(shí),selector.select()會返回
         * 如果該事件沒有到達(dá),selector.select()會一直阻塞
         */
        socketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void listen() throws IOException {
        while (true){
            //當(dāng)注冊的事件到達(dá)時(shí),方法返回,否則該方法一直阻塞
            selector.select();
            //獲取selector中選項(xiàng)的迭代器
            Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                //刪除已經(jīng)選擇的key,防止重復(fù)處理
                iterator.remove();
                //客戶端連接請求事件
                if(key.isAcceptable()){
                    //接收連接
                    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                    //獲取客戶端連接的通道
                    SocketChannel channel = serverSocketChannel.accept();
                    //設(shè)置為非阻塞
                    channel.configureBlocking(false);
                    //向客戶端發(fā)送數(shù)據(jù)源
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    String message = "你好我是服務(wù)器端,我接收到了你的消息";
                    buf.put(message.getBytes(StandardCharsets.UTF_8));
                    //把緩沖區(qū)切換成讀取模式
                    buf.flip();
                    //將buffer寫入channel
                    while (buf.hasRemaining()){
                        channel.write(buf);
                    }
                    //和客戶端連接成功后,為了接收到客戶端的信息,需要給通道設(shè)置讀取權(quán)限
                    channel.register(this.selector,SelectionKey.OP_READ);
                }else if(key.isReadable()){
                    //讀取數(shù)據(jù)
                    read(key);
                }
            }
        }
    }

    public void read(SelectionKey key) throws IOException {
        //得到事件發(fā)生的socket通道
        SocketChannel channel = (SocketChannel) key.channel();
        //創(chuàng)建讀取的緩沖區(qū)
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //將數(shù)據(jù)讀取到緩沖區(qū)
        channel.read(buffer);
        // 4、把緩沖區(qū)切換成寫出模式
        buffer.flip();
        String rs = new String(buffer.array(),0,buffer.remaining());
        System.out.println(rs);
    }

    public static void main(String[] args) throws IOException {
        NIOServer server = new NIOServer();
        server.initServer(8100);
        server.listen();
    }
}

客戶端文章來源地址http://www.zghlxwxcb.cn/news/detail-838529.html

public class NIOClient {
    //通道管理器
    private Selector selector;

    public static void main(String[] args) throws IOException {
        NIOClient client = new NIOClient();
        client.initClick("127.0.0.1",8100);
        client.listen();
    }
    public void initClick(String ip,int port) throws IOException {
        //獲取一個(gè)socket
        SocketChannel channel = SocketChannel.open();
        //設(shè)置通道為非阻塞
        channel.configureBlocking(false);
        //獲取一個(gè)通道管理器
        this.selector = Selector.open();

        channel.connect(new InetSocketAddress(ip,port));

        channel.register(this.selector, SelectionKey.OP_CONNECT);
    }

    public void listen() throws IOException {
        while (true){
            selector.select();
            Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isConnectable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    if(channel.isConnectionPending()){
                        channel.finishConnect();
                    }
                    //設(shè)置為阻塞
                    channel.configureBlocking(false);
                    //向客戶端發(fā)送數(shù)據(jù)源
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    String  message = "服務(wù)器端你好,我是客戶端";
                    buffer.put(message.getBytes(StandardCharsets.UTF_8));
                    //把緩沖區(qū)切換成讀取模式
                    buffer.flip();
                    //將buffer寫入channel
                    while (buffer.hasRemaining()){
                        channel.write(buffer);
                    }
                    channel.register(this.selector,SelectionKey.OP_READ);
                }else if(key.isReadable()){
                    read(key);
                }
            }
        }
    }

    public void read(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        channel.read(buffer);
        byte[] data = buffer.array();
        // 4、把緩沖區(qū)切換成寫出模式
        buffer.flip();
        String rs = new String(data,0,buffer.remaining());
        System.out.println(rs);
    }
}

到了這里,關(guān)于NIO核心三:Selector的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JAVA中三種I/O框架——BIO、NIO、AIO

    JAVA中三種I/O框架——BIO、NIO、AIO

    BIO,同步阻塞IO模型,應(yīng)用程序發(fā)起系統(tǒng)調(diào)用后會一直等待數(shù)據(jù)的請求,直至內(nèi)核從磁盤獲取到數(shù)據(jù)并拷貝到用戶空間; 在一般的場景中,多線程模型下的BIO是成本較低、收益較高的方式。但是,如果在高并發(fā)的場景下,過多的創(chuàng)建線程,會嚴(yán)重占據(jù)系統(tǒng)資源,降低系統(tǒng)對外

    2024年02月08日
    瀏覽(18)
  • Java中的三種I/O模型:BIO、NIO和AIO

    I/O(輸入/輸出)操作是任何應(yīng)用程序中必不可少的一部分,它涉及到與文件、網(wǎng)絡(luò)或其他設(shè)備之間的數(shù)據(jù)傳輸。Java提供了幾種不同的I/O模型,其中最常見的是AIO(異步非阻塞I/O)、BIO(阻塞I/O)和NIO(非阻塞I/O)。這些模型在處理I/O操作時(shí)具有不同的工作方式、特性和適用

    2024年02月08日
    瀏覽(22)
  • BIO、NIO和AIO

    BIO、NIO和AIO

    目錄 一.引言 何為IO IO的過程 Java的3種網(wǎng)絡(luò)IO模型 阻塞和非阻塞IO IO多路復(fù)用 異步和同步IO 二.BIO 三.NIO 1. 三大組件 Channel Buffer Selector 2.ByteBuffer 2.1ByteBuffer的使用 2.2ByteBuffer 結(jié)構(gòu) ?2.3ByteBuffer的常用方法 分配空間 ? 向 buffer 寫入數(shù)據(jù) 從 buffer 讀取數(shù)據(jù) 字符串與 ByteBuffer 互轉(zhuǎn) 分

    2024年02月12日
    瀏覽(23)
  • BIO、NIO、AIO區(qū)別詳解

    主線程發(fā)起io請求后,需要等待當(dāng)前io操作完成,才能繼續(xù)執(zhí)行。 引入selector、channel、等概念,當(dāng)主線程發(fā)起io請求后,輪詢的查看系統(tǒng)是否準(zhǔn)備好執(zhí)行io操作,沒有準(zhǔn)備好則主線程不會阻塞會繼續(xù)執(zhí)行,準(zhǔn)備好主線程會阻塞等待io操作完成。 主線程發(fā)起io請求后,不會阻塞,

    2024年02月07日
    瀏覽(29)
  • BIO、NIO、AIO 的區(qū)別

    Java面試題? 阻塞IO。一個(gè)連接一個(gè)線程,當(dāng)服務(wù)端接受到多個(gè)客戶端的請求時(shí),客戶端有連接請求時(shí)服務(wù)器端就需要啟動一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會造成不必要的線程開銷 同步非阻塞IO 。一個(gè)線程處理多個(gè)連接。NIO 包含? Channel(通道)、Selector(選擇

    2024年01月20日
    瀏覽(20)
  • BIO、NIO、AIO 有什么區(qū)別?

    Java 中的I/O模型主要分為三類:BIO(Blocking I/O)、NIO(New I/O)和AIO(Asynchronous I/O)。它們在處理I/O操作時(shí)有著不同的工作方式和特點(diǎn)。 BIO是傳統(tǒng)的I/O模型,也稱為同步I/O。在BIO中,每個(gè)I/O操作都會阻塞線程,直到數(shù)據(jù)準(zhǔn)備好或者操作完成。這意味著一個(gè)線程只能處理一個(gè)連

    2024年01月16日
    瀏覽(20)
  • BIO、NIO、AIO 有什么區(qū)別

    在Java中,BIO(Blocking I/O)、NIO(Non-blocking I/O)和AIO(Asynchronous I/O)都是用于處理I/O(輸入/輸出)操作的不同方式。它們在處理I/O時(shí)具有不同的特點(diǎn)和適用場景。 BIO(Blocking I/O): 阻塞式I/O模型,是Java最傳統(tǒng)的I/O模型。 在BIO中,每個(gè)I/O操作都會阻塞當(dāng)前線程,直到操作完

    2024年02月13日
    瀏覽(22)
  • Java NIO FileChannel:BIO與NIO區(qū)別、核心組成部分和常用方方法

    深入探討Java NIO中的FileChannel,包括BIO與NIO的區(qū)別、NIO的核心組成部分(Channels、Buffers、Selectors)、FileChannel的常用方法以及示例代碼。了解如何使用FileChannel進(jìn)行文件數(shù)據(jù)讀寫操作。

    2024年01月25日
    瀏覽(24)
  • NIO核心三:Selector

    NIO核心三:Selector

    選擇器提供一種選擇執(zhí)行已經(jīng)就緒的任務(wù)的能力。selector選擇器可以讓單線程處理多個(gè)通道。如果程序打開了多個(gè)連接通道,每個(gè)連接的流量都比較低,可以使用Selector對通道進(jìn)行管理。 1.創(chuàng)建Selector 2.必須將通道設(shè)置為非阻塞模式才能注冊到選擇器上 3.把通道注冊到選擇器上

    2024年03月11日
    瀏覽(22)
  • BIO、NIO、IO多路復(fù)用模型詳細(xì)介紹&Java NIO 網(wǎng)絡(luò)編程

    BIO、NIO、IO多路復(fù)用模型詳細(xì)介紹&Java NIO 網(wǎng)絡(luò)編程

    上文介紹了網(wǎng)絡(luò)編程的基礎(chǔ)知識,并基于 Java 編寫了 BIO 的網(wǎng)絡(luò)編程。我們知道 BIO 模型是存在巨大問題的,比如 C10K 問題,其本質(zhì)就是因其阻塞原因,導(dǎo)致如果想要承受更多的請求就必須有足夠多的線程,但是足夠多的線程會帶來內(nèi)存占用問題、CPU上下文切換帶來的性能問題

    2024年02月14日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包