Nio基本概念


一句话概述

Java Nio 可以做到用一个线程处理多个操作。假设有1000个请求过来,根据实际的情况可以分配20或者80个线程进行处理,不必像阻塞io那样需要启动1000个线程进行处理。

基本介绍

  • Nio与Io 有着相同的作用与目的,但是使用方式完全不同,Nio支持面向缓冲区、基于通道的Io操作。Nio为非阻塞Io,传统Io的read和write操作只能阻塞进行,线程在阻塞期间不能干其他的事;比如在调用socket.read时,如果服务器一直没发送数据过来,线程就一直阻塞等待数据的传输。
  • Nio的三大组件:Channel、Buffer、Selector
  • Java Nio的非阻塞模式,是一个线程从某通道发送数据或者读取数据,但它仅能得到目前可用的数据,如果目前没有数据,就什么也不会获取,而不是让线程阻塞,在数据可读取之前,该线程可以继续做其他的事;非阻塞写也是如此,一个线程请求写入数据到某通道,但不需要完全等待写完,该线程就可以继续做其他的事情。

Nio 与Bio的比较

  • Bio以流的方式处理数据,而Nio以块的方式处理数据,块io的效率比流io的高。
  • Bio是阻塞的,Nio为非阻塞的
  • Bio基于字节流与字符流进行操作,Nio基于通道和缓冲区进行操作,数据从通道写入缓冲区,或者从缓冲区读取到通道中,Selector用与监听多个通道的事件(比如链接请求、数据到达请求),因此单个线程就能监听多个客户端通道。

Nio 三大核心组件的示意图

Buffer
缓冲区本质上是一块可以读写数据的一块内存。
Channel
通道相比于流,及可以从通道中读取数据,也可以向通道中写入数据。但流的读写通常是单向的。通道可以非阻塞的读取和写入通道,也可以读取和写入缓冲区,也支持一异步的读写。
Selector
能够检查一个或多个Nio通道,并确定哪些通道已经准备好读取或写入。这样一个单独的线程可以管理多个channel,从而管理多个网络链接,提高效率。

  • 每个channel都对应一个buffer
  • 每个线程都对应一个selector,一个selector对应多个channel
  • 程序切换到那个channel由事件决定
  • selector根据不同的事件在各个channel上进行切换
  • buffer就是一块内存,底层是一个数组
  • 数据的读取和写入是由buffer完成的,Bio中要么事输入流要,要么是输出流,不能双向,但Nio的buffer是可以读写的。
  • Java Nio的核心是 Channel和Buffer。通道表示打开到Io的设备(文件、套接字)的连接。使用Java Nio首先获取连接io设备的channel ,并操作该channel对应的buffer,实现数据的处理。简言之:channel负责数据的传输,buffer负责数据的存储。