geekyouth / geekyouth.github.io

👣极客青年博客😘,基于github pages+issues + VUE 2.0 框架构建的轻量级静态博客系统💎[速度慢请翻墙]
https://java666.cn
39 stars 6 forks source link

Java基础—NIO基础概念 #6

Closed geekyouth closed 2 years ago

geekyouth commented 6 years ago

一、I/O & NIO

Java的IO流,根据类型不同划分为(具体继承这些IO类的子类非常多)

Java传统的IO类操作都是阻塞的,在高并发的场景下性能令人堪忧。

Java NIO(Non-blocking IO)是JDK1.4之后推出的一套新IO接口——非阻塞IO,与传统IO接口的主要区别在于:

I/O NIO
线程阻塞 线程非阻塞
用流(Stream)的方式处理数据 用缓冲区(Buffer)的方式处理数据

二、NIO基本概念

2.1 Channel

1). Channel,相对于Stream,有几点区别:

Channel Stream
双向(可以读写) 单向(只能读或只能写)
非阻塞操作 阻塞操作
基于Buffer 基于流

2). NIO数据的流向总是:

Channel ----> Buffer Channel <---- Buffer

3). Channel主要有下面几种类型:

类型 说明
FileChannel 文件的数据读写
DatagramChannel UDP的数据读写
SocketChannel TCP的数据读写
ServerSocketChannel 监听TCP链接请求,并且创建SocketChannel

4). 具体获取Channel的类

类型 说明
FileChannel FileInputStream.getChannel() FileOutputStream.getChannel() RandomAccessFile.getChannel()
DatagramChannel DatagramChannel.open()
SocketChannel SocketChannel.open()
ServerSocketChannel ServerSocketChannel.open()

2.2 Buffer

Buffer实际上就是一块内存区,用于和Channel交互,需要注意的是:

Buffer是非线程安全的,如果需要在多线程环境中使用,则需要有同步锁。

1). Buffer基本概念

要真正理解Buffer,有一张图比较经典:

通常,0 <= mark <= position <= limit <= capacity

buffers-modes

2). Buffer类型

Buffer名字 对应基础类型
ByteBuffer byte
CharBuffer char
DoubleBuffer double
FloatBuffer float
IntBuffer int
LongBuffer long

3). Buffer常用操作

buffer操作 具体
clear() limit=capacity, position=0, mark忽略
flip() limit= position, position=0, mark忽略
rewind() position=0, mark忽略
compact() (ByteBuffer才有) 将整块Buffer(从position~limit)移动到Buffer开始的位置(0~limit-position)

Buffer常用操作模式:

2.3 Selector

Selector是NIO中的组件,检查一个或多个channel,实现一个线程管理多个网络链接。

overview-selectors

使用步骤:

Channel必须是非阻塞的。所以FileChannel不适用Selector,因为FileChannel不能切换为非阻塞模式。Socket channel可以正常使用。

参考链接

https://github.com/johnnian/Blog/issues/36