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/ ...
随机推荐
- python编程【环境篇】- 如何优雅的管理python的版本
简介 之前的文章(Python2还是python3 )中我们提到,建议现在大家都采用python3,因为python2在今年年底将不在维护.但在实际的开发和使用python过程中,我们避免不了还得用到 ...
- sshd服务及基于密钥远程登陆(无需密码)
上一条博客说明了用sshd服务远程登陆另一个系统,但是需要密码,如果不用密码呢?有没有简便的方法呢?下面为大家介绍一下,也就是基于密钥的安全验证:需要在本地生成”密钥对“后将公钥传送至服务端,进行公共 ...
- Linux 常用命令 | free 详解
free命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及被内核使用的buffer.在Linux系统监控的工具中,free命令是最经常使用的命令之一.本文介绍free命令的使用方法和 ...
- 算法编程题积累(1)——网易笔试"工程师工作安排“问题
首先理解题目意思:每个人只能做工作序号表里的一件工作且两个人不能同时做一件工作.AC思路:采用暴力枚举每种可能的分配方案,子问题的解决逐步向上解决了母问题,最终原问题得解. 标程作者:NotDeep( ...
- 你了解MySQL中的锁吗?
MySQL中的锁,分为全局锁.表级锁.行锁 全局锁 全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL Flash tables with read lock 这个命令的语义是,使整个库处于 ...
- CMDB连接方式
1.agent agent (放在每台客户端服务器上,定时任务) 脚本演示 # 采集本机的信息 执行命令 import subprocess v1 = subprocess.getoutput('ip ...
- 2018年航空概论课后作业(PS:部分答案不正确, 综合得分:83.6)
1 [单选题]航空是指载人或不载人的飞行器在地球____的航行活动. • A.高空• B.大气层内• C.宇宙• D.大气层外我的答案:B 得分: 33.3分 2 [多选题]军用飞机可分为____两大 ...
- nyoj 33-蛇形填数 (循环,模拟)
33-蛇形填数 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:15 submit:38 题目描述: 在n*n方陈里填入1,2,...,n*n,要求填 ...
- 领扣(LeetCode)寻找峰值 个人题解
峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位 ...
- Prometheus+Altermanager钉钉报警
Prometheus+Altermanager钉钉报警 一.添加钉钉机器人 参考钉钉官方文档:https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq ...