1、什么时候注册可读,可写事件
Key在connect时注册为SelectionKey.OP_CONNECT,当检测到连接完成时,才将Key转换为可读或可写事件,key.interestOps(OP_WRITE/OP_READ);
key在bind时注册为SelectionKey.OP_ACCEPT,当检测到连接到来时,才将Key转换为可读或可写事件。
key不能随意注册为可写事件;当注册为可写事件时,只要buffer不满就可以写,selecotor总是可以检测到这个事件,实际是又没有东西可写返回0,
这样会浪费CPU资源,所以可写事件的注册,一般只在确实有数据要发送的时候才注册。
2、selector的select()函数是阻塞的,还是非阻塞的
当使用select()函数检测IO事件时,若没有IO事件,线程会阻塞在select函数上面,若想不一直阻塞,可以在select函数中添加参数,即超时时间。
3、为什么需要自己和自己的连接
在select的时候,如果队列有新的Channel加入,那么Selector.select()会被唤醒,然后重新select最新的Channel集合。
要唤醒select方法,只需要调用Selector的wakeup()方法。Selector的notify和wakeup的功能正是利用
在Windows建立的一对loopback的TCP连接,或在Linux建立的一对pipe的连接,当需要wakeup时,则往这对连接上面发送数据,当有数据时select将被唤醒。
4、nio和多线程的关系
传统的io阻塞模式是当有连接时就新建一个线程处理连接。
当客户端多时,会创建大量的处理线程。且每个线程都要占用栈空间和一些CPU时间;阻塞可能带来频繁的上下文切换,且大部分上下文切换可能是无意义的。
而nio是非阻塞的,基于事件模型,感兴趣的事情到了就处理。本来单个线程就可以处理所有这些事件,但根据不同的使用场景,可以引入多线程来提高效率。
比如起一个线程单独处理连接事件,当读写操作的工作量比较大时,可以起一个线程单独处理读写操作,从而提高效率。
java nio编程细节
最新推荐文章于 2023-08-03 22:37:21 发布