NIO -学习分享

简介: NIO -学习分享

NIO

BIO 阻塞 1链接1线程  线程阻塞
线程=clone进程
IO 中断     操作内核
man 2   kernel
代码追踪命令
strace -ff -o out  java  Class
encode 字符转为二进制
decode 二进制转字符
核心API
Channels
Buffers
Selectors

数据可以从channel 到 buffer
也可以从buffer到channel
既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
通道可以异步地读写。
通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

JavaNIO channel 的实现类
FileChannel  用于读取,写入,映射和操作文件的通道  文件通道可以安全使用多个并发线程
DatagramChannel 面向数据报的套接字的可选通道   数据报通道可以安全使用多个并发线程。
    他们支持并发读和写,但最多只有一个线程可能正在读取,并且最多一个线程可能在任何给定的时间写入。
SocketChannel  用于面向流的连接插座的可选通道  套接字通道可以安全地被多个并发线程使用。
ServerSocketChannel 用于面向流的侦听套接字的可选通道 服务器套接字通道可以安全地被多个并发线程使用。
Java NIO里关键的Buffer实现
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
MappedByteBuffer


Selector
Selector允许单线程处理多个 Channel
要使用Selector,得向Selector注册Channel,然后调用它的select()方法
这个方法会一直阻塞到某个注册的通道有事件就绪。
一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。


Buffer的capacity,position和limit

buffer 两种模式 写 和读  双游标指针


写模式下  limit =capacity       position 最大为 capacity-1
读模式下 position置0  position指针一直读取下一个可读元素并移动到下一个位置。 limit为position

分配Buffer  定义大小为48字节的buffer
ByteBuffer buf = ByteBuffer.allocate(48);
写数据到Buffer有两种方式:
从Channel写到Buffer。   int bytesRead = inChannel.read(buf); //read into buffer.
通过Buffer的put()方法写到Buffer里。buf.put(127)
flip()方法
flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值。
clear()与compact()方法
clear 重置position指针为0    数据并未清楚后续操作将会覆盖写数据
compact 首先将剩余未读取的数据copy到buffer开头 position为剩余数据的长度  

scatter / gather分散聚集
分散将channel中的数据分散写入多个buffer中
gather 聚集 将多个buffer中的数据聚齐写入channel中    scatter / gather经常用于需要将传输的数据分开处理的场合,例如传输一个由消息头和消息体组成的消息,你可能会将消息体和消息头分散到不同的buffer中,这样你可以方便的处理消息头和消息体。 (AMQP 消息 )

Scattering Reads 分散读取
消息体必须固定大小

Java

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

分散读取 模拟AMQP消息内容

// 创建缓冲区

ByteBufferhead=ByteBuffer.allocate(4);

ByteBufferbody=ByteBuffer.allocate(8);

ByteBuffer[]bufferArr={head,body};

longbyteRead=channel.read(bufferArr);

while(byteRead!=-1){

System.out.println("byteRead:"+byteRead);

// 把数据从文件channel里读到buffer里

// 反转buffer把buffer里的数据读到后清空buffer

// buffer反转

head.flip();

body.flip();

// 检查缓冲区是否有足够的空间

while(head.hasRemaining()){

System.out.print((char)head.get());

}

while(body.hasRemaining()){

System.out.print((char)body.get());

}

System.out.println();

head.clear();

body.clear();

byteRead=channel.read(bufferArr);

}


BIO,快递员通知你有一份快递会在今天送到某某地方,你需要在某某地方一致等待快递员的到来。

NIO,快递员通知你有一份快递会送到你公司的前台,你需要每隔一段时间去前台询问是否有你的快递。

AIO,快递员通知你有一份快递会送到你公司的前台,并且前台收到后会给你打电话通知你过来取。

transfer To

目录
相关文章
|
6月前
|
存储 弹性计算 监控
|
6月前
|
缓存 Java 索引
|
6月前
|
6月前
|
Java API
|
缓存 安全 Java
NIO基础
三大组件 Channel & Buffer channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是输入,要么是输出,channel 比 stream 更为底层 channel buffer 常见的 Channel 有 FileChannel DatagramChannel SocketChannel ServerSocketChannel buffer 则用来缓冲读写数据,常见的 buffer 有 ByteBuffer MappedByteB
42 0
|
存储 Java Linux
BIO、NIO、IO多路复用模型详细介绍&Java NIO 网络编程
上文介绍了网络编程的基础知识,并基于 Java 编写了 BIO 的网络编程。我们知道 BIO 模型是存在巨大问题的,比如 C10K 问题,其本质就是因其阻塞原因,导致如果想要承受更多的请求就必须有足够多的线程,但是足够多的线程会带来内存占用问题、CPU上下文切换带来的性能问题,从而造成服务端崩溃的现象。怎么解决这一问题呢?优化呗,所以后面就有了NIO、AIO、IO多路复用。本文将对这几个模型详细说明并基于 Java 编写 NIO。
328 0
|
网络协议 Java
NIO
NIO
106 0
|
存储 索引
NIO学习一
NIO相比普通IO提供了功能更为强大、处理数据更快的解决方案。 常用于高性能服务器上。NIO实现高性能处理的原理是使用较少的线程来处理更多的任务 常规io使用的byte[]、char[]进行封装,而NIO采用ByteBuffer类来操作数据,再结合 针对File或socket技术的channel,采用同步非阻塞技术来实现高性能处理,而Netty 正是采用ByteBuffer(缓冲区)、Channel(通道)、Selector(选择器)进行封装的。 因此我们需要先了解NIO相关的知识。
104 0
NIO学习一
|
前端开发 Java Linux
NIO学习笔记(三) 甚欢篇
NIO学习笔记(三) 甚欢篇
NIO学习笔记(三) 甚欢篇
|
存储 缓存 弹性计算