Java-NIO-Selector

本文详细介绍了Java NIO中的Selector,包括可选择通道(SelectableChannel)、选择键(SelectionKey)及其使用方法。通过示例代码展示了如何利用Selector进行非阻塞I/O操作,实现单线程管理多个网络连接,降低线程上下文切换的开销。同时讨论了停止选择的方法,如wakeup()和close()。最后提供了一个简单的Selector使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创文章:Java-NIO-Selector – 编程屋

目录

1 概述

2 Selector

2.1 可选择通道(SelectableChannel)

2.2 选择键 (SelectionKey)

2.3  方法示例

2.4 停止选择的方法

3 Selector演示小demo


1 概述

        Selector一般称之为选择器,也可以翻译为多路复用器。它是Java-NIO中核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。如此可实现单线程管理多个channels,也就是可以管理多个网络连接。

使用Selector的好处在于:使用更少的线程来就可以处理通道了,相比使用多个线程,避免了线程上下文切换带来的开销

2 Selector

2.1 可选择通道(SelectableChannel)

1)不是所有的Channel都能够被Selector复用的。像FileChannel就不能被选择器复用(因为它没有继承SelectableChannel).只有继承了SelectableChannel才能够被Selector复用。

2)SelectableChannel类提供了实现通道的可选择性所需要的公共方法。它是所有支持就绪检查的通道类的父类。所有的socket通道,都继承了SelectableChannel类都是可选择的,包括从管道(pipe)对象中或得的通道。而FileChannel类,没有继承SelectableChannel所以不是可选择通道。

3)一个通道可以被注册到多个选择器上,但对每个选择器而言只能被注册一次。通道和选择器之间的关系使用注册的方式完成

2.2 选择键 (SelectionKey)

1)Channel注册到后,并且一旦通道处于某种就绪的状态,就可以被选择器查询到。这个工作,使用选择器Selector的select()方法完成。select方法的作用,对感兴趣的通道操作,进行就绪状态的查询。

2)Selector可以不断查询Channel中发生的操作的就绪状态。并且挑选感兴趣的操作就绪状态。一旦通道有操作的就绪状态打成,并且是感兴趣的操作,就会被Selector选中,放进选择键集合

3)一个选择键,首先是包含了注册在Selector的通道操作的类型。也包含的特定的通道与特定的选择器之间的注册关系。

4)选择键的概念,和事件的概念比较相似。一个选择键类似于监听模式里边的一个事件。由于Selector不是事件触发的模式而是主动去查询的模式,所以不叫事件event ,而是叫SelectionKey选择键。

2.3  方法示例

 public static void main(String[] args) throws IOException {

        //创建selector
        Selector selector = Selector.open();

        //通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        //非阻塞
        serverSocketChannel.configureBlocking(false);

        //绑定连接
        serverSocketChannel.bind(new InetSocketAddress(9999));

        //将通道注册到选择器上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        //查询已经就绪通道操作
        Set<SelectionKey> selectionKeys = selector.selectedKeys();
        //遍历集合
        Iterator<SelectionKey> iterator = selectionKeys.iterator();
        while (iterator.hasNext()) {
            SelectionKey key = iterator.next();
            //判断key就绪状态操作
            if (key.isAcceptable()) {

            }else if (key.isConnectable()){

            }else if (key.isReadable()){

            }else if (key.isWritable()) {

            }
        }
        iterator.remove();

    }

2.4 停止选择的方法

选择器执行选择的过程,系统底层会依次询问每个通道是否就绪,这个过程可能会造成调用线程进入阻塞状态,那么有以下方法可以唤醒select()方法中阻塞的线程

1)wakeup() 方法:通过调用Selector对象的wakeup()方法让处在阻塞状态下selector()立刻返回。该方法使得选择器上的第一个还没返回的选择操作立即返回。如果当前没有进行中的选择操作,那么下一次对selector()方法的一次调用将立即返回。

2)close()方法:通过close()方法关闭Selector。该方法使得任何一个在选择操作中阻塞的线程都被唤醒,同时使得注册到该Selector的所有Channel被注销,所有的建都会取消,但是channel本身不会关闭

3 Selector演示小demo

先启动服务端,在启动main方法

以上只是部分内容,为了维护方便,本文已迁移到新地址:Java-NIO-Selector – 编程屋

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值