IO到NIO的一个转变
本内容来源:Jack视频讲解和自己的一个理解。
1、故事还得从网络模型或者IO开始聊起
2、你有想过传统IO真正存在的问题吗?
3、如果你是设计者,IO可以怎样改进?
4、NIO原理分析以及代码实现
IO:不就是input和output吗。input:输入操作;output:输出操作;从jdk出生开始他就已经存在了,在jdk的java.io包下面。
我们都知道io是阻塞 io,那么想一下为什么是阻塞的?来看看下面这个IO的一个测试类
package com.test; import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; /**
* @Title: BIOServer
* @Description: IO 测试
* @author: sunxuesong@hztianque.com
* @date: Created in 20:05 2019/9/8
* @Modifired by:
*/
public class BIOServer {
public static void main(String[] args) {
try{
// socket监听,端口8888
ServerSocket serverSocket = new ServerSocket();
System.out.println("BIOServer has started,listening on port:" + serverSocket.getLocalSocketAddress());
// 不停的监听有没有客户端进行链接
while (true) {
// 进行链接
Socket clientSocket = serverSocket.accept();
System.out.println("Connect from " + clientSocket.getRemoteSocketAddress());
try {
// 客户端输入的内容
Scanner input = new Scanner(clientSocket.getInputStream());
// 这个while是用来客户端和服务器进行交互的,通过输出流进行数据写出
while (true) {
String request = input.nextLine();
if ("quit".equals(request)) {
break;
}
System.out.println(String.format("From %s : %s", clientSocket.getRemoteSocketAddress(), request));
String response = "From BIOServer Hello:" + request +".\n";
clientSocket.getOutputStream().write(response.getBytes());
}
}catch (Exception e) {
e.printStackTrace();
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
启动上面的main方法服务进行测试一下:
打开cmd 输入 telnet localhost 8888 回车,链接进来后,随便输入然后回车可以在控制台看到你输入的内容,这时候在来重新打开一个cmd,之前的cmd窗口不要关闭,这时候可以链接进来,但是这时候不管你怎么输入控制台都不会有反应,这是为什么呢?因为被阻塞了,在队列中进行等待,如果你关闭之前的cmd窗口,这时候控制台会立马看到你输入的内容。那既然这样就会有人说了我们可以使用多线程去操作,这种想法很好,在tomcat1.7之前tomcat也是这么做的,比如我用一个线程池大小是3,这时候最多支持3个客户端链接可以进行交互,如果第四个来了那么只能阻塞等待,因为前面的线程没有进行释放。
来看一下IO的模型:
1.阻塞io(Blocking I/O)
我来描述一下怎么请求的:首先用户去请求读取磁盘数据,这时候磁盘数据是受保护的不允许你直接去读取,它必须通过内核空间去读取(这是计算机自己的一个机制,分为用户空间和内核空间,用户空间就是我们的java进程,内核空间是计算机自己分配的),那么java是怎么做的呢?将请求交给内核空间,其他不用你去管。那么当java进程去内核空间拿数据的时候,这时候发现内核空间还没有将数据准备好,那他就会一直等待着,直到你准备好了为止。这时候等待的状态就是一个阻塞的状态,他不会释放cpu的资源。其他线程无法进行访问。
2:非阻塞IO(No Blocking I/O)
这个是怎么用的呢?我来解释一下他和上面的区别主要在于他不会去等待内核空间,当内核空间没有准备好数据的时候他直接返回了,不会占用资源。
3:复用IO
这种IO他不会一直等待,他有一个专门的线程来管理所有的客户端请求。他会一直轮询,知道发现有一个socket是read状态然后进行数据的一个读取。
这时候NIO就孕育而生了,他对上面的几个模型进行了一个取长补短的操作。
首先基于这种高速的请求,那么客户端的链接速度肯定是跟不上的,于是nio发明了selector的思想,多路复用的一个概念,多路:多个TCP链接(Socket或者Channel)。
多路复用:当一个或多个客户端进行链接的时候,统一由多路复用器进行管理(一个单独的线程)这时候由内核进行监视多路复用器里面的socket,这时候用户进程是阻塞的,当任何一个socket数据准备好了,多路复用器都会返回,这时候用户进程再调用read操作把数据从内核缓存区拷贝到用户空间。
下节用源码说明一下nio的一个机制。他用到了复用IO的selector机制,然后他发现内核空间进行复制磁盘数据的时候也是需要等待的,这时候他又引入了一个buffer的概念,buffer是一个可变的缓冲池,默认是1024个字节,当发现buffer中的缓冲池不够的时候会自动的扩容。
IO到NIO的一个转变的更多相关文章
- java IO和NIO 的区别
Java NIO和IO的主要区别 下表总结了Java NIO和IO之间的主要差别. IO NIO 面向流 面向缓冲 阻塞IO 非 ...
- java的nio之:java的nio系列教程之java的io和nio的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- 面试题_66_to_75_Java IO 和 NIO 的面试题
IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...
- 传统IO与NIO的比较
本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...
- Java IO 和 NIO
昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
- IO 和 NIO 的思考
输入输出是操作系统不可或缺的一部分,大致分为两类:面向磁盘和面向网络.在 Java 中有3种 I/O 类型:BIO.NIO 和 AIO,分别是同步阻塞.同步非阻塞和异步非阻塞 I/O,这里着重描述 B ...
- 理解IO、NIO、 AIO
转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...
- Java IO、NIO、AIO知识总结
本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到. 本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助. https://www.cnblogs.com/ ...
随机推荐
- 还看不懂同事的代码?Lambda 表达式、函数接口了解一下
当前时间:2019年 11月 11日,距离 JDK 14 发布时间(2020年3月17日)还有多少天? // 距离JDK 14 发布还有多少天? LocalDate jdk14 = LocalDate ...
- 使用Typescript重构axios(三十一)——添加axios.all和axios.spread方法
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- SP5150 JMFILTER - Junk-Mail Filte(并查集)
直秒并查集.这题的难点就在于怎么删点.如果要删的是叶节点,那还好,直接刨掉即可 如果是中间节点甚至是根节点,那就不好办了..... solution: 对于独立一个点,我可以用邻接表模拟,然后用并查集 ...
- 使用Samba服务实现文件共享
1.在虚拟机上安装Samba服务安装包 (在下载之前检查客户机与服务器是否能够ping通) (鼠标右击桌面,打开终端,测试和yum是否能够ping通,下面的命令行是我的yum的IP地址) [root@ ...
- Python OpenCV4趣味应用系列(四)---颜色物体实时检测
今天,我们来实现一个视频实时检测颜色物体的小实例,视频中主要有三个颜色物体,我们只检测红色和绿色的球状物体,如下图所示: 第一步需要打开视频(或者摄像头): cap = cv2.VideoCaptur ...
- Git常用命令(基础)
Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 一.新建代码库 # 在当前目录新建一个Git代码库 $ git in ...
- (C#)WPF:LinearGradientBrush的使用
在MSDN文档库里可以查到,Rectangle.Fill的类型是Brush.Brush是一个抽象类,凡是以Brush为基类的类都可作为Fill属性的值.Brush的派生类有很多: * SolidCol ...
- 小白学 Python 爬虫(1):开篇
人生苦短,我用 Python 引言 各位同学大家好,好久不见(可能只有一两天没见:囧)~~~ 先讲一件事情,昨天为啥没更新. emmmmmmmmm,当然是因为加班啦,快到年底了,公司项目比较忙,最近的 ...
- [UWP]用Win2D实现镂空文字
1. 前言 之前用PointLight做了一个番茄钟,效果还不错,具体可见这篇文章: [UWP]使用PointLight并实现动画效果 后来试玩了Win2D,这次就用Win2D实现文字的镂空效果,配合 ...
- [Part 4] 在Windows 10上源码编译PCL 1.8.1支持VTK和QT,可视化三维点云
本文首发于个人博客https://kezunlin.me/post/2d809f92/,欢迎阅读! Part-4: Compile pcl with vtk qt5 support from sour ...