JAVA NIO

NIO

 

  1. 每个channel都会对应一个buffer
  2. selector对应一个线程一个线程对应多个channel
  1. 改图反映三个channel注册到改selector程序
  2. 程序切换到哪个channel是由事件决定的,Event就是一个重要的概念
  1. Selector会根据不同的事件,在各个通道上切换
  2. Buffer就是一个内存块,底层是有一个数组
  1. 数据的读写都是通过Buffer,可以双向读写,需要flip方法切换
  2. channel是双向的,可以返回底层操作系统的情况,比如Linux,底层操作系统通道也是双向的

缓冲区(Buffer)

基本介绍

缓冲区(buffer):缓冲区的本质是一个可以读写数据的内存块,可以理解成是一个容器对象(含数组),该对象提供了一组方法,可以轻松地使用内存块,缓冲区对象内置了一些机制,能跟踪和记录缓冲区的状态变化情况。Channel提供文件、网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer

Buffer类及子类

  1. Buffer是一个顶层父类,它是一个抽象类
  1. Buffer类定义了所有的缓冲区都有四个属性来提供关于其包含的数据元素

  Capacity 容量,即可以容纳的最大数据量;在缓冲区创建时被设定且不能改变

  Limit 表示缓冲区的当前终点,不能对缓冲区超过极限位置进行读写操作。且极限是可以修改的。

  Position 位置,下一个要被读写的元素的索引。每次读写缓冲区数据都会改变值,为下次读写做准备

  Mark 标记

 

通道(Channel)

  1. NIO的通道类似于流,但有如下区别:
  • 通道可以同时进行读写,而流只能读或者只能写
  • 通道可以实现异步读写数据
  • 通道可以从缓冲中读数据,也可以写数据到缓冲中
  1. BIO中的stream是单向的,例如FileInputStream对象只能进行读取数据的操作,而NIO中的通道(Channel)是双向的,可以读操作也可以写操作
  1. Channel在NIO中是一个接口public interface Channel extends Closeable{}
  2. 常用的Channel类有:FileChannel、DatagramChannel、SocketChannel
  1. FileChannel用于文件数据的读写,DatagramChannel用于UDP的数据读写 ServerSocketChannel和SocketChnnnel用于TCP的读写

选择器(Selector)

  1. Java的NIO,用非阻塞的IO方式。可以用一个线程,处理多个的客户端连接,就会使用到Selector
  2. Selector能够检测多个注册的通道上是否有事件发送(多个Channel以事件的方式可以注册到同一个Selector)

如果有事件发生,便获取事件然后针对每个事件进行相应的处理,这样就可以用一个单线程去管理多个通道,也就是管理多个连接和请求。

  1. 只有在连接真正有读写发生时,才会进行读写,就大大地减少了系统开销,并且不必为每一个连接都创建一个线程,不用去维护多个线程
  2. 避免了多线程之间的上下文切换导致的开销

selector类相关方法

public static Selector open(); //得到一个选择器对象

public int Select(long timeout);//监控所有注册的通道,当其中有IO操作可以进行,将对应的SelectionKey加入到内部集合并返回,参数用来设置超时事件

public Set<SelectionKey>selectedKeys;//从内部集合中得到所有SelectionKey

SelectionKey

  1. SelectionKey,表示SelectionKey和网络通道的注册关系,共四种:

  int OP_ACCEPT: 有新的网络连接可以accept,值为16

  int OP_CONNECT: 表示连接已经建立,值为8

  int OP_READ: 代表读操作,值为1

  int OP_WRITE: 代表写操作,值为4

  1. SelectionKey的相关方法

  Selector selector(); //得到与之关联的Selector对象

  SelectableChannel channel(); //得到与之关联的通道

  Object attachment(); //得到与之关联的共享数据

  SelectionKey interestOps(int ops);//设置或改变监听事件

  boolean isAcceptable();//是否可accept

  boolean isReadable();//是否可读

  boolean isWritable();//是否可写

ServerSocketChannel

  1. ServerSocketChannel在服务器监听新的客户端Socket连接
  2. 相关方法如下

  ServerSocketChannel open();//得到一个ServerSocketChannel通道

  ServerSocketChannel bind(SocketAddress local);//设置服务器端口端口号

  ServerSocketChannel configureBlocking(boolean block);//设置阻塞或非阻塞模式

  SelectionKey register(Selector sel,int ops);//注册一个选择器并设置监听事件

SocketChannel

  1. SocketChanel,网络IO通道,具体负责进行读写操作。NIO把缓冲区的数据写入通道,或者把通道的数据读到缓冲区。
  2. 相关方法如下

  SocketChannel open(); //得到一个SocketChannel通道

  SocketChannel configureBlocking(boolean block);//设置阻塞或非阻塞模式

  connect(SocketAddress remote);//连接服务器

  boolean finishConnect();//如果上面的方法连接失败,接下来就要通过该方法完成连接操作

  int write(ByteBuffer src);//往通道里写数据

  int read(ByteBuffer dst);//往通道里读数据

 

 

posted @ 2021-08-05 13:54  南无象海豹  阅读(51)  评论(0)    收藏  举报