选择器(Selector) 是 SelectableChannle 对象的多路复用器,Selector 可以同时监控多个 SelectableChannel 的 IO 状况,也就是说,利用 Selector可使一个单独的线程管理多个 Channel,selector 是非阻塞 IO 的核心。

SelectableChannle 的继承树如下图:

选择器(Selector)的应用:

当通道使用register(Selector sel, int ops)方法将通道注册选择器时,选择器对通道事件进行监听,通过第二个参数指定监听的事件类型。

其中可监听的事件类型包括以下:

  读 : SelectionKey.OP_READ (1)

  写 : SelectionKey.OP_WRITE (4)

  连接 : SelectionKey.OP_CONNECT (8)

  接收 : SelectionKey.OP_ACCEPT (16)

如果需要监听多个事件是:

  int key = SelectionKey.OP_READ | SelectionKey.OP_WRITE ; //表示同时监听读写操作

如何应用请看代码:

public class NIOBlocking2 {

   //客户端
@Test
public void client() throws Exception {
//1. 获取socketChannel
SocketChannel sChannel = SocketChannel.open();
//2. 创建连接
sChannel.connect(new InetSocketAddress("127.0.0.1", 9898));
ByteBuffer buf = ByteBuffer.allocate(1024);
//3. 设置通道为非阻塞
sChannel.configureBlocking(false); @SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String msg = scanner.nextLine(); buf.put((new Date() + ":" + msg).getBytes());
buf.flip();
//4. 向通道写数据
sChannel.write(buf);
buf.clear();
}
}

   //服务端
@Test
public void server() throws Exception {
//1. 获取服务端通道
ServerSocketChannel ssChannel = ServerSocketChannel.open();
ssChannel.bind(new InetSocketAddress(9898));
//2. 设置为非阻塞模式
ssChannel.configureBlocking(false); //3. 打开一个监听器
Selector selector = Selector.open();
//4. 向监听器注册接收事件
ssChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) {
//5. 获取监听器上所有的监听事件值
Iterator<SelectionKey> it = selector.selectedKeys().iterator(); //6. 如果有值
while (it.hasNext()) {
//7. 取到SelectionKey
SelectionKey key = it.next(); //8. 根据key值判断对应的事件
if (key.isAcceptable()) {
//9. 接入处理
SocketChannel socketChannel = ssChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
//10. 可读事件处理
SocketChannel channel = (SocketChannel) key.channel();
readMsg(channel);
}
//11. 移除当前key
it.remove();
}
}
} private void readMsg(SocketChannel channel) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(1024);
int len = 0;
while ((len = channel.read(buf)) > 0) {
buf.flip();
byte[] bytes = new byte[1024];
buf.get(bytes, 0, len);
System.out.println(new String(bytes, 0, len));
}
} }

NIO的非阻塞性:

nio的非阻塞是对于网络通道来说的,需要使用Channel.configureBlocking(false)来设置通道为非阻塞的,如果没设置,默认是阻塞的。

Java NIO (四) 选择器(Selector)的更多相关文章

  1. Java NIO之选择器Selector

    在单独的线程中,检查多个通道是否可以进行IO操作. Selector创建:静态工厂方法创建 Selector selector = Selector.open(); 注册通道 channel.conf ...

  2. 【NIO】Java NIO之选择器

    一.前言 前面已经学习了缓冲和通道,接着学习选择器. 二.选择器 2.1 选择器基础 选择器管理一个被注册的通道集合的信息和它们的就绪状态,通道和选择器一起被注册,并且选择器可更新通道的就绪状态,也可 ...

  3. java输入输出 -- Java NIO之选择器

    一.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector.在更早的文章中,我简述了几种 IO 模型.如果大家看过之前的文章,并动手写过代码的话.再 ...

  4. Java NIO:选择器

    最近打算把Java网络编程相关的知识深入一下(IO.NIO.Socket编程.Netty) Java NIO主要需要理解缓冲区.通道.选择器三个核心概念,作为对Java I/O的补充, 以提升大批量数 ...

  5. Java NIO之选择器

    1.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector.在更早的文章中,我简述了几种 IO 模型.如果大家看过之前的文章,并动手写过代码的话.再 ...

  6. 7. 彤哥说netty系列之Java NIO核心组件之Selector

    --日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第七篇. 简介 上一章我们一起学习了Java NIO的核心组件Buffer,它通常跟Channel一起使用,但是它们在网络IO中又该如何 ...

  7. Java NIO学习系列三:Selector

    前面的两篇文章中总结了Java NIO中的两大基础组件Buffer和Channel的相关知识点,在NIO中都是通过Channel和Buffer的协作来读写数据的,在这个基础上通过selector来协调 ...

  8. Java NIO学习系列四:NIO和IO对比

    前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...

  9. Java NIO (转)

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...

  10. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

随机推荐

  1. Teredo Tunnel Adapter: Error Code 10

    Teredo Tunneling 该设备无法启动 错误代码 ErrCode:10 解决方法 前文: Win7 系统,打算开启IPV6,本地连接的网络 ip6 驱动是异常的,先重新安装了网卡驱动. 过程 ...

  2. 当final作用于变量、参数、方法和类时该如何处理

    final变量: 对于基本类型使用final:它就是一个常量,数值恒定不变 对于对象引用使用final:使得引用恒定不变,一旦引用被初始化指向一个对象,就无法再把 它改为指向另一个对象.然而,对象自身 ...

  3. Lonlife 1000 - Spoon Devil's 3-D Matrix

    1000 - Spoon Devil's 3-D Matrix Time Limit:1s Memory Limit:32MByte Submissions:208Solved:65 DESCRIPT ...

  4. 深入理解javascript函数进阶系列第三篇——函数节流和函数防抖

    前面的话 javascript中的函数大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理,否则一般不会遇到跟性能相关的问题.但在一些少数情况下,函数的触发不是由用户直接控制的.在这些场景 ...

  5. C#换行 System.Environment.NewLine。

    为保持平台的通用性,可以用系统默认换行符 System.Environment.NewLine.

  6. AngularJS 控制器通信

    指令与控制器之间通信,无非是以下几种方法: 基于scope继承的方式 基于event传播的方式 service的方式 基于scope继承的方式 最简单的让控制器之间进行通信的方法是通过scope的继承 ...

  7. Apache+PHP+MySQL+phpMyAdmin环境搭建

    最近在学习web服务端开发,一开始是使用wamp的,后来决定自己完整配置一下环境,并把整个过程记录下来.其中,Apache是服务器,php是用来编写服务端的语言,MySQL作为数据库,phpMyAdm ...

  8. Java 模拟栈结构

    栈和队列: 通常是作为程序猿的工具,用于辅助构思算法.生命周期较短,执行时才被创建 訪问受限.在特定时刻,仅仅有一个数据可被读取或删除 是一种抽象的结构.内部的实现机制.对用户不可见.比方用数组.链表 ...

  9. openstack-glance API 镜像管理的部分实现和样例

    感谢朋友支持本博客,欢迎共同探讨交流,因为能力和时间有限.错误之处在所难免.欢迎指正. 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  10. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 Excel Services中新功能

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序  Excel Services中新功能         从S ...