按照缓冲区的顺序,分散读取和非阻塞式网络通信区别

2021-09-26 17:48:11 浏览数 (2)

分散读取

分散读取(Scattering Reads)是指从Channel 中读取的数据“分散”到多个Buffer 中。

注意:按照缓冲区的顺序,从Channel 中读取的数据依次将 Buffer 填满。

聚集写入

聚集写入(Gathering Writes)是指将多个Buffer 中的数据“聚集”到Channel。

按照缓冲区的顺序,写入position 和limit 之间的数据到Channel。

代码语言:javascript复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class demo6 {
    public static void main(String[] args) throws IOException {
        FileInputStream is = new FileInputStream("");
        FileOutputStream os = new FileOutputStream("");

        FileChannel inChannel = is.getChannel();
        FileChannel outChannel = os.getChannel();

        // 获得多个缓冲区,并且放入到缓冲区数组中
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(50);
        ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024);
        ByteBuffer[] byteBuffers = {byteBuffer1, byteBuffer2};

        // 分散读取
        inChannel.read(byteBuffers);

        byteBuffer1.flip();
        byteBuffer2.flip();

        // 聚集写入
        outChannel.write(byteBuffers);
    }
}

非阻塞式网络通信

概念

比喻:

代码语言:javascript复制
举个你去饭堂吃饭的例⼦,你好⽐⽤户程序,饭堂好⽐操作系统。

阻塞 I/O 好⽐,
你去饭堂吃饭,但是饭堂的菜还没做好,然后你就⼀直在那⾥等啊等,

等了好⻓⼀段时间终于等到饭堂阿姨把菜端了出来(数据准备的过程),

但是你还得继续等阿姨把菜(内核空间)打到你的饭盒⾥(⽤户空间),

经历完这两个过程,你才可以离开。



⾮阻塞 I/O 好⽐,
你去了饭堂,问阿姨菜做好了没有,阿姨告诉你没,

你就离开了,过⼏⼗分钟,你⼜来,

饭堂问阿姨,阿姨说做好了,于是阿姨帮你把菜打到你的饭盒⾥,这个过程你是得等待的。




基于⾮阻塞的 I/O 多路复⽤好⽐,
你去饭堂吃饭,发现有⼀排窗⼝,饭堂阿姨告诉你这些窗⼝都还没做好菜,

等做好了再通知你,于是等啊等( select 调⽤中),过了⼀会阿姨通知你菜做好了,

但是不知道哪个窗⼝的菜做好了,你⾃⼰看吧。

于是你只能⼀个⼀个窗⼝去确认,后⾯发现 5 号窗⼝菜做好了,

于是你让 5 号窗⼝的阿姨帮你打菜到饭盒⾥,这个打菜的过程你是要等待的,虽然时间不⻓。

打完菜后,你⾃然就可以离开了。



异步 I/O 好⽐,
你让饭堂阿姨将菜做好并把菜打到饭盒⾥后,把饭盒送到你⾯前,整个过程你都不需要任何等待。

0 人点赞