一文读懂NIO

本文从操作系统基础知识入手,详细解释了BIO、NIO和多路复用器的工作原理,揭示了BIO的弊端以及NIO如何解决这些问题。通过分析Java中的NIO实现,探讨了Selector在处理并发连接中的作用,最后介绍了AIO的基本概念,为读者提供了一条从BIO到非阻塞IO的清晰路径。
摘要由CSDN通过智能技术生成

前言

NIO看了好多的博客、视频,都学不明白,最多只是单纯的记住了代码而已,时间一久就忘得一干二净,更不用说学习更牛逼的Netty,Nginx,Redis的底层原理了。
所以这篇博客从底层讲起,从操作系统上的BIO到Non-blocking IO到Java中的NewIO,只有真正理解了原理,才能学会NIO。

操作系统知识

首先要有一点操作系统的前置知识。

系统调用的概念

都知道操作系统中分为用户态(可以理解为应用程序所在的空间)和内核态(可以理解为操作系统内核所在的空间)。用户态是不能直接访问内核态的,要访问内核态需通过系统调用的方式。系统调用可以简单的理解为内核态提供的的一些api,用户态没有权限访问一些资源,只能通过调系统调用来切换为内核态,让内核态访问。
在切换为内核态时,cpu要将当前运行程序的一些缓存数据和当前指令等保存到程序所在内存空间中(即保护现场),内核态切换回用户态时要去把这一部分数据从内核态拷贝回来(即恢复现场)。很直观的一个结论:频繁的用户态内核态切换,一定会影响性能
此外还有个时钟中断的概念,假设只有一个cpu,但现代操作系统仍然可以运行多个进程(线程),这是因为每隔一段时间cpu就收到一个时钟中断、表示当前需要切换进程(线程)运行了,宏观的感觉就是1颗cpu上并行运行了多个程序,实际上在微观每个时间点还是只能运行单个程序的,进程(线程)之间的切换也需要保护/恢复现场,也是会影响性能

strace命令

strace命令常用于跟踪用户态向内核态发起的系统调用,并记录在一个文件里面。我们可以用它来跟踪java程序,并在对应的文件里找到当前java程序到底向内核态发起了什么样的系统调用。

man命令

man命令是查询linux帮助文档,比如man 2 xxx表示查询xxx的系统调用的详情(系统调用的代号为2)。
以上2个命令具体详解百度,这里只需要大概知道它们的作用就行了。

socket

我的理解socket就是对一个网络连接的抽象(或者说操作系统定义的规范?),比如服务器153.1.1.1:8081和客户端142.1.1.1:8088建立了一个连接,这一对ip+port就可以被称为一个scoket。
服务器的ip+port和客户端的ip+port,有任意一个不同都是不同的socket。

fd

fd即file description(文件描述符),Linux中一切皆文件,一个socket也会在操作系统中以一个fd文件的形式保存下来。
socket和fd的详情也可以百度,这里只需知道大概作用,直接看后文的实际操作就行。

BIO

首先写一个BIO的程序,然后用strace命令跟踪,看这个程序它在底层到底做了啥。
一个最简单的BIO程序

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author MasterYee
 * @Description:
 * @date: 2020/7/15
 */
public class BIOTest {
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值