IO模型-NIO选择器

为了将Channel和Selector配合使用,channel必须注册到selector上。通过SelectableChannel.register()方法来实现.Channel必须处于非阻塞模式下。这意味着不能将FileChannel与Selector一起使用,因为FileChannel不能切换到非阻塞模式。而套接字通道都可以

基于选择器,Java 的 NIO,用非阻塞的 IO 方式。可以用一个线程,处理多个的客户端连接,避免了多线程之间的上下文切换导致的开销

SelectionKey key = channel.register(selector,Selectionkey.OP_READ);

第二个参数,Selector监听Channel时对什么事件感兴趣。可以监听四种不同类型的事件:

  • SelectionKey.OP_CONNECT 某个channel成功连接到另一个服务器称为“连接就绪”

  • SelectionKey.OP_ACCEPT 一个server socket channel准备好接收新进入的连接称为“接收就绪”

  • SelectionKey.OP_READ 一个有数据可读的通道可以说是“读就绪”

  • SelectionKey.OP_WRITE 等待写数据的通道可以说是“写就绪

 

注意:

  • client的socketChannel:只监听 连接、读、写事件
  • server的serverSocketChannel 只监听OP_ACCEPT
  • server的socketChannel只监听 读、写事件 注册好之后会有一个多路复用器selector去循环检测对于管道上是否有该事件发生。

注册后返回一个 SelectionKey,SelectionKey,表示 Selector 和网络通道的注册关系

通过SelectionKey可以获取与之关联的Selector,channel,再完成后续业务处理

 

Selector 常用方法

public abstract class Selector implements Closeable { 
    public static Selector open();//得到一个选择器对象
    public int select();//阻塞到至少有一个通道在你注册的事件上就绪了。返回有事件发生的通道的个数.
    public int select(long timeout);//监控所有注册的通道,当其中有 IO 操作可以进行时,将
    对应的 SelectionKey 加入到内部集合中并返回,参数用来设置超时时间,返回有事件发生的通道的个数.
    public int selectNow();//不阻塞,立马返还。此方法执行非阻塞的选择操作。如果自从前一次选择操作后,没有通道变成可选择的,则此方法直接返回零,返回有事件发生的通道的个数.
    public Set<SelectionKey> selectedKeys();//从内部集合中得到所有的 SelectionKey	
    
    public abstract Selector wakeup();//某个线程调用select()方法后阻塞了,即使没有通道已经就绪,也有办法让其从select()方法返回。只要让其它线程在第一个线程调用select()方法的那个对象上调用Selector.wakeup()方法即可。阻塞在select()方法上的线程会立马返回。
    public abstract void close() throws IOException;//用完Selector后调用其close()方法会关闭该Selector,且使注册到该Selector上的所有SelectionKey实例无效。通道本身并不会关闭。
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值