1.JAVA-IO模型概述

102 阅读3分钟

三种IO模型介绍

BIO(Blocking IO):同步阻塞IO,在服务器程序中,一个请求就要对应一个线程来处理,客户端发起请求,服务器如果没有足够的线程来响应,请求就会阻塞(这就是阻塞的地方),直到有可用的线程处理请求,处理完成后才能返回给客户端。即使该请求只是想读取一个几KB的数据。服务器维护线程池有很大的开销,大量的线程切换也会降低程序性能。

阻塞IO模型虽然性能不高,但实现简单而且支持很多场景,比如轻量级请求、重量级请求、持久连接。服务器程序tomcat、apache就是用阻塞IO实现的

Java.io包下的工具类就是BIO的实现,阻塞就是 线程 调用 read,线程卡住了,只能等读取完成才能返回。非阻塞就是 线程调用 read,线程立即能拿到返回值

NIO(No Blocking IO):同步非阻塞IO,当一个线程执行从Channel读取数据的IO操作时,如果有数据,则返回数据。如果没数据也不需要阻塞,而是直接返回。

Java NIO是jdk1.4推出的非阻塞IO模型,非阻塞IO读写比普通IO更快,并且是基于内存的buffer缓冲区,还支持通道读取,性能很高,netty也是基于NIO开发的

Java NIO还支持多路复用模式,使用一个或少量线程来监听通道,减少了线程,避免频繁切换线程带来的消耗,构建服务器程序的性能提高

异步IO:AIO,

了解了各种IO模型后,再看用户态和内核态

操作系统为了保护系统安全,划出了用户态和内核态两种操作权限,以linux为例,内核可以操控任意的硬件,写入数据到磁盘任意的位置,权限是非常大的。但是应用程序不可以,如果安装了一个危险的应用程序,这个程序非法篡改了磁盘甚至系统文件。那么操作系统安全就不能保证了。所以操作系统将不同层面的程序封装了不同的操作权限,大体就可分为用户态和内核态,应用程序只能调用操作系统的函数来完成一系列操作,调用后内核到底如何操作的应用程序是不知道的。

例如Java写入文件,JVM底层函数库调用操作系统接口,操作系统再调用内核将文件写入。JVM并不知道文件具体的写入步骤,写到了哪,只知道文件写入成功了。

Java.IO操作时,就是用户态调用内核态的poll方法,此时可以看做用户态切换到了内核态。poll方法是阻塞的,所以io包下的各种工具类是阻塞式。

通常来说,一个丰富的程序运行中,需要各种硬件来支撑,内核态切换也很频繁,如果每次系统调用的函数都是阻塞式的,那么程序的性能也得不到提高。