Selector(选择器)是 Channel 的多路复用器,它可以同时监控多个 Channel 的 IO 状况,允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。
选择器、通道、缓冲池是NIO的核心组件。
一、新建选择器
此时选择器内只包含这一条负责监听连接请求的通道
二、减少阻塞之事件触发送到嘴边
一、不用阻塞等待建立连接
答:最最关键的一步是选择器的存在,同时下图第一个红框,ServerSocketChannel属性设置为非阻塞也有一定作用
选择器监听通道,所监视的正是通道中的事件,key就代表通道中出现的事件,在循环开始后,选择器调用select() 方法监控选择器中通道状态
有 3 种方式可以 select 就绪事件:
1)select() 阻塞方法,只要出现一个就绪事件就会返回。没有则一直保持阻塞状态。
2)select(long timeout) 阻塞方法,有一个就绪事件,或者其它线程调用了 wakeup(),或者当前线程被中断,或者阻塞时长达到了 timeout 时返回。不抛出超时异常。
3)selectNode() 不阻塞,如果无就绪事件,则返回 0;如果有就绪事件,则将就绪事件放到一个集合,返回就绪事件的数量。
那么select方法实现了什么? 这个方法实现了选择器中的通道只有 出现一批就绪事件才会主动去处理,若没有就绪事件就等着啥也不干。
这个是NIO选择器的优势:来活了才干,不来活就等着,没活干了也不占坑死等(存在就绪事件的通道才会占用资源,减少功耗)
当第一次开始循环,选择器中只有一个ServerSocketChannel通道,也就是说这时只能进行客户端到服务端的连接,上图中红框key.channel()就是获得当前事件所在的ServerSocketChannel,
调用accept()方法就相当于:如