Selector selector = Selector.open();

普通的IO流的读取,写入都是一个字节一个字节或一个字符一个字符的循环进行,在这个过程中,程序是阻塞的,inputStream虽然既可以一个字节一个字节的读

inputSream.read(),也可以批量读.inputStream.read(byte[], pos, length),但这样频繁io导致效率很低。虽然也有bufferedInputStream,bufferedOutputStream,

自带缓冲区,但依旧是阻塞的。这样在面对多个连接时,就需要启多个线程,而大量的线程会占用太多的系统资源,线程的切换也会导致效率下降。

而新的IO体系,NIO,可以解决上诉问题。

NIO体系中几个新概念:

1 Buffer

Buffer:NIO中新建的类,包含数据的线性表结构。

2 Charset

设置加码解码规则

<span style="white-space:pre">	</span>@Test
public void test1() throws IOException{
Charset charset = Charset.forName("GBK");
String str = "hello。中国";
ByteBuffer byteBuffer = charset.encode(str);//将字符流转换成字节流,设置转换字符集
<pre name="code" class="java"><span style="white-space:pre"> </span>//Charset charset1 = Charset.forName("UTF-8");//解码字符集与加码的字符集不一样的化,出现乱码,因为字符转换成字节编码规则的不同转换的字节个<span style="white-space:pre"> </span> //数也不相同

Charset charset1 = Charset.forName("GBK");CharBuffer charBuffer = charset1.decode(byteBuffer);//将字节流转换成字符流,需要对应的字符集System.out.println(charBuffer.toString());}


3  Channel

信道,负责读取,写入Buffer中数据,并与底层网络交互。

4   Selector

解决多元异步IO操作在一个或很少的线程中执行。

数据流图:
数据发送端 -->发送端Buffer缓冲区 --> 发送端Channel  ---> 网络 --> 接收端Channel  -->接收端Buffer缓冲区  -->数据接收端

Selector如何实现无阻塞IO

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

2. 注册Channel

SelectionKey key = channel.register(selector, SelectionKey.OP_ACCEPT)
SelectionKey:Channel向Selector注册时返回的身份标识,每个Channel都有一个SelectionKey,注册时同时加入自己感兴趣的事件。

SelectionKey对应一个Selector和一个Channel;

SelectableChannel channel = selectionKey.channel();
Selector  selecotr = selectionKey.selector();

事件类型有:SelectionKey.OP_ACCEPT:接受连接就绪事件
SelectionKey.OP_CONNECT:连接成功就绪事件

SelectionKey.OP_READ,:读就绪事件

SelectionKey.OP_WRITE:写就绪事件

3. Selector.select()

返回已准备就绪的通道的SelectionKey的个数。就绪表明有Channel中发生了以上四种类型事件的一种或几种。
int select():阻塞到至少有一个通道在你注册的事件上就绪了。
int select(long timeout):和select()一样,除了最长会阻塞timeout毫秒(参数)。
int selectNow():不会阻塞,不管什么通道就绪都立刻返回,此方法执行非阻塞的选择操作。如果自从前一次选择操作后,没有通道变成可选择的,则此方法直接返回零。
4. selector.selectedKeys()
Set selectedKeys = selector.selectedKeys();

如果select返回的值不为0,表明有通道上发生事件,则可通过selectedkeys获取所有的key,再通过对应的事件类型在对应的Channel上进行对应的读,写操作。





最新文章

  1. mysql学习之触发器
  2. Accessorizer的使用说明!
  3. ASP.NET MVC 5 学习教程:快速入门
  4. js中字符串转换为数字的方法
  5. java——操作文件
  6. 服务器 libevent中epoll使用实例demo
  7. asp.net导出excel较为简约的代码
  8. BlockingQueue-线程的阻塞队列
  9. Error: theForm.submit is not a function !!
  10. 学习React系列(一)——React.Component 生命周期
  11. 请求http页面的相关过程
  12. chage命令
  13. 福利爬虫妹子图之获取种子url
  14. windows无法安装到这个磁盘。选中的磁盘采用GPT分区形式 Windows 检测到 EFI 系统分区格式化为 NTFS。将 EFI 系统分区个数化为 FAT32,然后重新启动安装
  15. 【转】 如何导入excel数据到数据库,并解决导入时间格式问题
  16. 【git】git简单使用教程
  17. 机械加工行业计划排程:中车实施应用易普优APS
  18. HihoCoder - 1445 后缀自动机 试水题
  19. BAT-Java必考面试题集
  20. MEF教程

热门文章

  1. php不允许用户提交空表单(php空值判断)
  2. HTML5:一个拖拽网页元素的例子
  3. shutdown computer in ad and ou
  4. html 各个标签初始化
  5. iOS开发之本地化
  6. iOS Xcode制作模板类-b
  7. 通过本地加载ga.js文件提高Google Anlytics性能
  8. bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp
  9. 制作PPT时,可能这些小习惯你需要注意
  10. csu 10月 月赛 F 题 ZZY and his little friends