本内容来源: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的一个转变的更多相关文章

  1. java IO和NIO 的区别

    Java NIO和IO的主要区别 下表总结了Java NIO和IO之间的主要差别. IO                NIO 面向流            面向缓冲 阻塞IO           非 ...

  2. java的nio之:java的nio系列教程之java的io和nio的区别

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

  3. 面试题_66_to_75_Java IO 和 NIO 的面试题

    IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...

  4. 传统IO与NIO的比较

    本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...

  5. Java IO 和 NIO

    昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...

  6. JAVA中IO和NIO的详解分析,内容来自网络和自己总结

    用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...

  7. IO 和 NIO 的思考

    输入输出是操作系统不可或缺的一部分,大致分为两类:面向磁盘和面向网络.在 Java 中有3种 I/O 类型:BIO.NIO 和 AIO,分别是同步阻塞.同步非阻塞和异步非阻塞 I/O,这里着重描述 B ...

  8. 理解IO、NIO、 AIO

    转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...

  9. Java IO、NIO、AIO知识总结

    本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到. 本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助. https://www.cnblogs.com/ ...

随机推荐

  1. 在linux用ueditor遇到的问题

    在使用ueditor时,遇到很多问题.最大问题是就是服务器返回出错 最让人头疼的是preview没有任何信息.之前也找过很多的资料,很多资料都没有提到修改controller.php文件中error_ ...

  2. css3自定义移动端滚动条

    css3自定义移动端滚动条<pre>/*定义滚动条宽 高度是根据内容设置的高度决定的*/::-webkit-scrollbar{ width: 5px;} /*定义滚动条轨道 内阴影+圆角 ...

  3. html5 textarea 写入换行的方法

    html5 textarea 写入换行的方法<pre> <textarea id="fwe" class="selmiao" cols=&qu ...

  4. Python面向对象 | 类的成员

    一. 细分类的组成成员 之前咱们讲过类大致分两块区域,静态字段部分和方法部分. 每个区域详细划分又可以分为: class A: company = '阿里巴巴' # 静态变量(静态字段) __tel ...

  5. 极&#183;Java速成教程 - (1)

    序言 众所周知,程序员需要快速学习新知识,所以就有了<21天精通C++>和<MySQL-从删库到跑路>这样的书籍,Java作为更"高级"的语言也不应该落后, ...

  6. nyoj 324-猴子吃桃问题 (m[i] = (m[i-1] + 1) * 2)

    324-猴子吃桃问题 内存限制:64MB 时间限制:3000ms 特判: No 通过数:20 提交数:21 难度:0 题目描述: 有一堆桃子不知数目,猴子第一天吃掉一半,又多吃了一个,第二天照此方法, ...

  7. ArcGIS API For Javascript :双屏(多屏)地图联动的方法

    在遇到地图对比的应用场景下,我们需要双屏地图或者多屏地图来满足我们的业务需求. 解决思路:首先生成两份(多份)地图,然后通过监听地图缩放拖拽,用地图四至将不同的地图对象做绑定,实现多地图联动. 前端部 ...

  8. 领扣(LeetCode)寻找峰值 个人题解

    峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位 ...

  9. gdb(ddd,kdevelop等)调试ZeroIce开发的应用程序,中断信号引起的问题

    不作文,只记要点. 1.Ice::Application的程序框架默认对SIGHUP, SIGINT, SIGTERM进行处理.目的就是捕捉Ctrl+C发出信号有序地结束程序.这个功能扰乱了我们使用g ...

  10. 2019-9-28:渗透测试,基础学习,pgp常量,逻辑运算,DNS投毒,笔记

    sunny.exe clientid 隧道ID route -n 查看网关netstat -rn 查看网关 DNS劫持ettercap用来内网渗透测试使用,可以嗅探内网,DNS劫持等攻击1,在攻击者电 ...