图解Java IO模型 admin 2023-02-10 16:24:02 篇首语:本文由小编为大家整理,主要介绍了图解Java IO模型相关的知识,希望对你有一定的参考价值。 对于 Java 的 IO 模型,对于大多数小伙伴都不陌生。但是想要准确的讲述这些 IO 模型之间的不同特点以及应用的范围,可能有一部分小伙伴很难讲清楚。在这篇文章中,我将尽可能清楚的讲述这些问题,希望对于坐在屏幕面前的你有一定的帮助。 在这篇文章中,我会先叙述 Linux 的 IO 模型,因为对于一些基本概念同步、异步、阻塞、非阻塞 Linux 和 Java 都是一致的,而且 Linux 的模型和 Java 的 IO 模型有相似的地方,或者说 Java 的 IO 模型有参考 Linux 的 IO 模型的地方。 Linux IO 模型 概念 内核态会涉及到一些比较底层或者比较危险的指令。如果对于用户开放的话,会造成比较危险的状况,所以用户不能直接调用这些指令。用户需要借助系统调用才能执行一些相关的操作。 同步/异步关注的是消息通信机制 。 同步:就是在发出一个调用时,在没有得到结果之前, 该调用就不返回。异步:调用在发出之后,这个调用就直接返回了,所以没有返回结果。 阻塞/非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。 阻塞:指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞:指在不能立刻得到结果之前,该调用不会阻塞当前线程。 举个简单的例子。 淘宝双 11 活动,小图同学买了一本《图解 Java》的书,此时快递小哥正在派送快递的情景。 同步、异步 同步、异步一般发生在不同的线程/进程之间。如果调用者发起调用,能马上获得调用结果,这就是异步调用。如果不能马上获得结果,需要等待被调用的线程/进程一段时间,才能获得结果,这就是同步调用。 阻塞、非阻塞 阻塞、非阻塞一般发生在单个进程/线程中。当进程/线程想要进行 A 操作,但是不能立刻完成(需要其他的条件 C)。如果线程/进程一直等待,不执行其他的操作,即此时处于阻塞状态。如果该线程/进程又开始执行另外的操作 B,此时线程处于非阻塞状态。 Linux IO 模型 根据前面描述的内核态和用户态的相关概念。当应用程序发起文件调用的时候,用户态运行的程序必须委托系统调用来访问硬件和内存。这个过程主要分为两个阶段,等待数据和将数据从内核拷贝到用户空间。根据这两个阶段中,调用进程和内核进程的表现,分为五种模型。 阻塞 IO 模型: 调用进程会一直阻塞,直到数据拷贝完成 。即应用程序调用一个 IO 函数,导致应用程序阻塞,等待数据准备好。数据准备好后,从内核拷贝到用户空间,IO 函数返回成功指示。在整个调用过程中都是阻塞的。 非阻塞 IO 模型: 调用进程在等待数据的过程中,会不断轮询数据有没有准备好。数据准备好后,从内核拷贝到用户空间,IO 函数返回成功指示。在等待数据的过程中是非阻塞的;将数据从内核拷贝到用户空间是阻塞的。 IO 复用模型: 在非阻塞 IO 模型中,需要调用线程不断去轮询,检查数据有没有准备好,在这个过程中消耗了 CPU 大量的时间。如果有其他的线程帮助去检查多个线程数据的完成状态,这样会提高效率。 Linux 提供了select、poll和epoll帮助我们。一个线程可以对多个 IO 端口进行监听,当 socket 有读写事件时分发到具体的线程进行处理。 select、poll、epoll 区别总结: 支持一个进程打开连接数 IO 效率 消息传递方式 select 32 位机器 1024 个,64 位 2048 个 IO 效率低 内核需要将消息传递到用户空间,都需要内核拷贝动作 poll 无限制,原因基于链表存储 IO 效率低 内核需要将消息传递到用户空间,都需要内核拷贝动作 epoll 有上限,但很大,2G 内存 20W 左右 只有活跃的 socket 才调用 callback,IO 效率高 通过内核与用户空间共享一块内存来实现 信号驱动式 I/O: 首先我们允许 Socket 进行信号驱动 IO,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用 I/O 操作函数处理数据。 异步 IO 模型: 相对于同步 IO,异步 IO 不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到 socket 数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。IO 两个阶段,进程都是非阻塞的。 以上是关于图解Java IO模型的主要内容,如果未能解决你的问题,请参考以下文章 pnputil.exe无法识别为内部或外部命令[关闭] pandas使用drop函数删除dataframe中的指定单个数据列或者多个数据列(drop a single column or multiple columns) 您可能还会对下面的文章感兴趣: 相关文章 浏览器打不开网址提示“ERR_CONNECTION_TIMED_OUT”错误代码的解决方法 如何安装ocx控件 VMware的虚拟机为啥ip地址老是自动变化 vbyone和EDP区别 linux/debian到底怎么重启和关机 苹果平板键盘被弄到上方去了,如何调回正常? 机器学习常用距离度量 如何查看kindle型号