面试问题浓缩总结 面试问题浓缩总结
  • Go
  • Java
  • C/C++
  • JavaScript/HTML
  • MySQL
  • Redis
  • MongoDB
  • 操作系统
  • 计算机网络
  • spring全家桶
  • mybatis
  • 中间件
  • 软件相关
  • 系统相关
  • 算法
  • 数据结构
  • 设计模式
  • CMU硕士经典100题
  • 剑指offer
  • 重点手撕代码
  • 程序员面试金典
  • 3月
  • 4月
  • 智力题
  • 业务问题
  • 一些技术
  • 安全相关
APP下载 (opens new window)
GitHub (opens new window)
  • Go
  • Java
  • C/C++
  • JavaScript/HTML
  • MySQL
  • Redis
  • MongoDB
  • 操作系统
  • 计算机网络
  • spring全家桶
  • mybatis
  • 中间件
  • 软件相关
  • 系统相关
  • 算法
  • 数据结构
  • 设计模式
  • CMU硕士经典100题
  • 剑指offer
  • 重点手撕代码
  • 程序员面试金典
  • 3月
  • 4月
  • 智力题
  • 业务问题
  • 一些技术
  • 安全相关
APP下载 (opens new window)
GitHub (opens new window)
  • Go

  • JAVA

    • java基础
    • 面向对象
    • 集合框架
    • 并发框架(JUC)
    • IO NIO框架
      • 基本概念介绍
      • Netty
      • IO流
        • Java 中 IO 流分为几种?
        • 既然有了字节流为什么还要有字符流?
    • JVM模型
    • 类加载机制
    • 垃圾回收
    • 参数调优
    • java8特性
    • 面试题
    • 其他
    • Java书籍学习笔记
  • C、C++语言

  • JavaScript和HTML

  • Android相关

  • 程序语言
  • JAVA
小游
2021-03-20

IO NIO框架

这里主要涉及到IO多路复用

# 基本概念介绍

BIO 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

ServerSocket 负责绑定 IP 地址,启动监听端口;Socket 负责发起连接操作,连接成功后,双方通过输入和输出流进行同步阻塞通信。采用 BIO 通信模型的 Server,通常由一个独立的 Acceptor 线程负责监听 Client 端的连接,它接受到 Client 端连接请求后为每个 Client 创建一个新的线程进行处理,处理完之后,通过输出流返回给 Client 端,线程销毁,过程如下图所示

传统 Java BIO 模型

这个模型最大的问题是:

  • 缺乏扩展性,不能处理高性能、高并发场景,线程是 JVM 中非常宝贵的资源,当线程数膨胀后,系统的性能就会急剧下降,随着并发访问量的继续增大,系统就会出现线程堆栈溢出、创建新线程失败等问题,导致 Server 不能对外提供服务。

NIO 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

与 Socket 类和 ServerSocket 类相对应,NIO 也提供了 SocketChannel 和 ServerSocketChannel 两种不同套接字通道的实现,它们都支持阻塞和非阻塞两种模式。一般来说,低负载、低并发的应用程序可以选择同步阻塞 IO 以降低复杂度,但是高负载、高并发的网络应用,需要使用 NIO 的非阻塞模式进行开发。

在 NIO 中有三种非常重要的概念:

  • 缓冲区(buffer):本质上是一个数组,它包含一些要读写的数据;
  • 通道(channel):是一个通道,通过它读写数据,类似于自来水管;
  • 多路复用器(selector):用于选择已经就绪的任务,selector 会轮询注册在其上的 channel,选出已经就绪的 channel。

NIO 的简单模型

  • Buffer:是缓冲区,任何时候访问 NIO 数据,都是通过 Buffer 进行;
  • Channel:通过它读写 Buffer 中的数据,可以用于读、写或同时读写;
  • Selector:多路复用器,Selector 不断轮询注册在其上的 Channel,如果某个 Channel 有新的 TCP 链接接入、读和写事件,这个 Channel 就处于就绪状态,会被 Selector 轮组出来,然后通过SelectionKey() 可以获取就绪 Channel 的集合,进行后续的 IO 操作。

关于 Java NIO,有两种最常见的使用方式:

  • 使用原生的 Java NIO(如 Kafka);
  • 使用 Netty(Hadoop 的 RPC 框架 Avro 底层使用 Netty 做通信框架)。

在实际使用中,推荐第二种,使用 Netty 将会大大提高开发效率,后续会写篇关于 Netty 的文章,介绍一下 Netty 的具体内容,这里使用一个基于 Java 原生 NIO API 的小示例,讲述一下 NIO 的使用方法。

AIO 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理.AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

参考:

谈一谈 Java IO 模型 | Matt's Blog (matt33.com) (opens new window)

# Netty

Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。Netty是基于nio的,它封装了jdk的nio,让我们使用起来更加方法灵活。

Netty (opens new window)为什么没有用JDK自带的多路复用器(没答上来,提示JDK空轮训BUG)聊了聊Netty (opens new window)前身

Netty面试题(2020最新版)_ThinkWon的博客-CSDN博客_netty面试题 (opens new window)

# IO流

# Java 中 IO 流分为几种?

  • 按照流的流向分,可以分为输入流和输出流;
  • 按照操作单元划分,可以划分为字节流和字符流;
  • 按照流的角色划分为节点流和处理流。

IO-操作对象分类

# 既然有了字节流为什么还要有字符流?

问题本质想问:不管是文件读写还是网络发送接收,信息的最小存储单元都是字节,那为什么 I/O 流操作要分为字节流操作和字符流操作呢?

回答:字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。

编辑 (opens new window)
上次更新: 2021/04/22, 17:24:44
并发框架(JUC)
JVM模型

← 并发框架(JUC) JVM模型→

Theme by Vdoing | Copyright © 2021-2021 小游
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式