nio和io的区别在哪,为什么io无法实现非阻塞

小编 286

nio和io的区别在于:面向对象不同、模式不同、选择器不同。io各种流是阻塞的,要实现非阻塞io,其方法主要有两个,一是打开文件时添加O_NONBLOCK标志;二是打开普通文件后,使用fcntl函数设置文件描述符的属性。

1.nio和io的区别

nio和io是java语言中的术语,两者的主要区别如下:

(1)面向对象不同

Java中,nio和io之间名列前茅个最大的区别是,nio是面向缓冲区的,io是面向流的。io面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。

(2)阻塞模式不同

nio的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。

io各种流是阻塞的,就是当一个线程调用读写方法时,该线程会被阻塞,直到读写完,在这期间该线程不能干其他事。

(3)选择器不同

nio的选择器允许一个单独的线程来监视多个输入通道。你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道。这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制使得一个单独的线程很容易来管理多个通道。

而io没有选择器,它原生的三大组件分别是:selector、Channel、ByteBuffer。

2.io实现非阻塞的方法

当用户线程发起一个IO操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送IO操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。那么如何实现非阻塞式IO呢?主要以下两种方法:

  • 方法一:打开文件时添加O_NONBLOCK标志。
  • 方法二:普通打开文件后,使用fcntl函数设置文件描述符的属性。

延伸阅读

IO多路复用的概念

IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄。一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出cpu。IO是指网络IO,多路指多个TCP连接(即socket 或者channel),复用指复用一个或几个线程。意思说一个或一组线程处理多个TCP连接。最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程。

IO多路复用的三种机制:

  • select机制:Windows、Linux;
  • poll机制:Linux #和lselect监听机制一样,但是对监听列表里面的数量没有限制,select默认限制是1024个,但是他们两个都是操作系统轮询每一个被监听的文件描述符(如果数量很大,其实效率不太好),看是否有可读操作;
  • epoll机制:Linux #它的监听机制和上面两个不同,他给每一个监听的对象绑定了一个回调函数,你这个对象有消息,那么触发回调函数给用户,用户就进行系统调用来拷贝数据,并不是轮询监听所有的被监听对象,这样的效率高很多。

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部