“NIO”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
第24行: 第24行:
 
为了更容易地理解什么是 Channel,这里以 InputStream 为例来介绍什么是 Channel。
 
为了更容易地理解什么是 Channel,这里以 InputStream 为例来介绍什么是 Channel。
  
传统的 IO 中经常使用下面的代码来读取文件:
+
传统的 IO 中经常使用下面的代码来读取文件:<syntaxhighlight lang="java">
 +
import java.io.*;
 +
 
 +
public class NIOTest {
 +
 
 +
    public static void main(String[] args) throws IOException {
 +
 
 +
        File file = new File("input.txt");
 +
        InputStream is = new FileInputStream(file);
 +
        byte[] b = new byte[1024];
 +
        int read = 0;
 +
        while ((read = is.read(b)) != -1) {
 +
            //处理读取到的数据
 +
        }
 +
        is.close();
 +
 
 +
    }
 +
 
 +
}
 +
</syntaxhighlight>

2023年5月9日 (二) 00:49的版本

在 NIO(Nonblocking IO,非阻塞 IO)出现之前,Java 是通过传统的 Socket 来实现基本的网络通信功能的。

以服务端为例,其实现基本流程如图所示。

Socket 使用流程.png

如果客户端还没有对服务端发起连接请求,那么 accept 就会阻塞[阻塞指的是暂停一个线程的执行以等待某个条件发生(例如某资源就绪)]。

如果连接成功,当数据还没有准备好的时候,对 read 的调用同样会阻塞。

当要处理多个连接的时候,就需要采用多线程的方式,由于每个线程都拥有自己的栈空间,而且由于阻塞会导致大量线程进行上下文切换,使得程序的运行效率非常低下。

因此在 J2SE 1.4 中引入了 NIO 来解决这个问题。


NIO 通过 Selector、Channels 和 Buffers 来实现非阻塞的 IO 操作。

NIO 是指 New I/O,既然有 New I/O,那么就会有 Old I/O,Old I/O 是指基于流的 I/O 方法。

NIO 是在 Java 1.4 中被纳入 JDK 中的,它最主要的特点是,提供了基于 Selector 的异步网络 I/O,使得一个线程可以管理多个连接。

基于 NIO 处理多个连接的结构图:

生成缩略图出错:无法将缩略图保存到目标地点

在介绍 NIO 的原理之前,首先介绍几个重要的概念:Channel(通道)、Buffer(缓冲区)和 Selector(选择器)。


Channel(通道)

为了更容易地理解什么是 Channel,这里以 InputStream 为例来介绍什么是 Channel。

传统的 IO 中经常使用下面的代码来读取文件:

import java.io.*;

public class NIOTest {

    public static void main(String[] args) throws IOException {

        File file = new File("input.txt");
        InputStream is = new FileInputStream(file);
        byte[] b = new byte[1024];
        int read = 0;
        while ((read = is.read(b)) != -1) {
            //处理读取到的数据
        }
        is.close();

    }

}