java-NIO基础

一、 Java NIO和传统IO的对比

比对项

传统IO

NIO(Non-Block IO)

缓冲

面向流

面向块(缓冲)

IO模型

阻塞IO

非阻塞IO

线程复用

选择器

二、 java NIO类库简介

2.1 Buffer缓冲区(特点:面向块)

传统JavaIO是面向流的I/O。流I/O一次处理一个字节。NIO则是面向块的I/O,每次操作都是以数据块为单位。它们的差距就好象两个人吃饭,一个人一粒一粒的吃,另一个人狼吞虎咽,快慢显而易见。NIO中引入了缓冲区(Buffer)的概念,缓冲区作为传输数据的基本单位:块。Buffer缓冲区的引入,是NIO与传统IO的一个重要区别.在传统IO中,都是针对流数据的操作,在NIO中是针对缓冲区数据操作。 缓冲区的实质是一个数组,最常用的是ByteBuffer.事实上每一种java基本类型都对应一种缓冲区类型.

2.2 Channel通道

Channel是数据通道,它与传统IO Stream的主要区别在于通道是双向读写的,流只是朝着一个方向移动 Channel可以主要分为2大类:一类为网络数据读写的SelectableChannel和文件读写的FileChannel.

2.3 多路复用器选择器Selector

Selector类是NIO的核心类,Selector能够检测多个注册的通道上,是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。

2.4 文件锁定,内存映射等其他新特性

  • 文件锁定是多个进程协同工作的情况下,要协调进程间对共享数据的访问必不可少的工具。
  • 内存映射利用虚拟内存技术提供对文件的高速缓存,使读取磁盘文件就像从内存中读取一样高效,但是却不会有内存泄漏的危险,因为在内存中不会存在文件的完整拷贝。

三、 IO模型

JDK4提供了非阻塞IO的能力,JDK7开始提供异步IO能力(NIO2.0)

3.1 阻塞I/O

  • 同步阻塞IO

在数据没有读写完成之前,线程不可以进行下一步操作,这样线程只好眼睁睁的在那里傻等。 下图为采用阻塞IO的通讯模型的服务端,由一个Acceptor监听客户端的链接,它接收到客户端的请求后创建一个新的线程进行链路处理,通过输出流应答客户端,线程销毁。简单地说就是,一客户端请求对应一个线程.

这个模型有一个很大的问题,就是当客户端请求规模较大的时候,一客户端请求创建一个线程,导致服务器资源消耗殆尽,造成宕机。

  • 伪异步IO(线程池)

为了解决这个问题,在服务端使用线程池。线程的数量是固定的(线程池),使用的时候借用获取,用完之后不是销毁而是将线程归还给线程池。但这个解决方案,在并发量超过线程池内现成的数量时,会导致获取线程的时间拉长,应答缓慢,延迟较大!这个方案,我们称为"伪异步IO"!

3.2 非阻塞I/O(Non-Block IO)

  • 传统JavaIO是基于阻塞I/O模型的:当发起一个I/O请求时,如果数据没有准备好(read时无可读数据,write时数据不可写入),那么线程便会阻塞,直到数据准备好,导致线程大部分的时间都在阻塞。
  • 非阻塞I/O则允许线程在有数据的时候处理数据,没有数据的时候释放CPU资源,提高了资源利用率。在数据没有准备好之前,调用线程可以离开,只需要每隔一段时间回来询问一次。

3.3 异步I/O

在数据没有读写完成之前,调用线程可以离开也不用轮询。在数据准备好之后,多路复用监听会主动通知调用线程。这通常需要复杂的设计,为降低NIO与AIO的实现复杂度,我们可以使用Netty或者mina等框架。

喜欢 (9)or分享 (0)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 8成以上的java线程状态图都画错了,看看这个-图解java并发第二篇

    在开始想写这篇文章之前,我去网上搜索了很多关于线程状态转换的图,我惊讶的发现:超过80%的图都是不完整的,或者是错的。所以我只好再次去阅读源码,然后画出下面的这...

    字母哥博客
  • 详解线程池的作用及Java中如何使用线程池

    服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发、耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操...

    字母哥博客
  • Docker安全之用户资源隔离

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的。...

    字母哥博客
  • NIO你真正了解多少?

    原文:http://www.java520.cn/java%E5%9F%BA%E7%A1%80/133.html

    李红
  • NIO你真正了解多少?

    类通过实现 Java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。

    李红
  • 『互联网架构』软件架构-tomcat之线程源码熟悉通信方式(上)(21)

    tomcat6.0之前都是用的BIO,8.0是默认的BIO,传统的java IO来进行的其实就是socket。

    IT故事会
  • NIO概述

    服务器实现模式为一个请求一个线程,但客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

    潇洒
  • Java程序员月薪达到三万,需要技术水平达到什么程度?(文末送书)

    最近跟朋友在一起聚会的时候,提了一个问题,说Java程序员如何能月薪达到三万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到。也许...

    芋道源码
  • Java程序员月薪达到三万,需要技术水平达到什么程度?

    非著名程序员
  • 【Kaggle】Intro to Machine Learning 第一次提交 Titanic

    各个 tab 下可以查看数据Data、代码编写Notebooks、讨论、排名、比赛规则、队伍

    Michael阿明

扫码关注云+社区

领取腾讯云代金券