0
点赞
收藏
分享

微信扫一扫

Netty_Day2_Selector

椰果玩安卓 2022-02-20 阅读 87

多路复用

单线程可以配合 Selector 完成对多个 Channel 可读写事件的监控,这称之为多路复用

多路复用仅针对网络 IO,普通文件 IO 无法利用多路复用
如果不用 Selector 的非阻塞模式,线程大部分时间都在做无用功,而 Selector 能够保证
有可连接事件时才去连接
有可读事件才去读取
有可写事件才去写入
限于网络传输能力,Channel 未必时时可写,一旦 Channel 可写,会触发 Selector 的可写事件

事件的四种类型:
accept:有连接请求触发
connet:是客户端连接建立后触发
read:可读事件
write:可写事件

服务端代码:

package com.ityin.netty.c1;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static com.ityin.netty.c1.ByteBufferUtil.debugRead;
@Slf4j
public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建selector,管理多个channel
        Selector selector=Selector.open();
        //使用nio来理解阻塞模式,单线程
        ByteBuffer buffer =ByteBuffer.allocate(16);
        ServerSocketChannel ssc=ServerSocketChannel.open();
        ssc.configureBlocking(false);
        //2.建立selector和channe之间的联系(注册)
        //SelectionKey是事件发生后,通过它来得知哪个channel的事件
        SelectionKey ssckey=ssc.register(selector,0,null);//0表示不关注任何事件
        //key只关注accept事件
        ssckey.interestOps(SelectionKey.OP_ACCEPT);
        log.debug("register key:{}",ssckey);
        ssc.bind(new InetSocketAddress(8080));
        while(true){
            //3.select方法,没有事件就阻塞,有事件线程恢复运行
            selector.select();
            //4.处理事件,selectedKeys内部包含了所有发生的事件
            Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
            while(iter.hasNext()){
                SelectionKey key=iter.next();
                log.debug("register key:{}",key);
                ServerSocketChannel channel=(ServerSocketChannel) key.channel();
                channel.accept();
                log.debug("{}",ssc);
            }
        }
    }
}

客户端触发后:
在这里插入图片描述
selector在事件未处理时不会阻塞,但是可以使用

key.cancel();

取消

举报

相关推荐

0 条评论