NIO 深入详解和重要体系分析

1、Java NIO 开发的注意点

  • IntBuffer.allocate(10) 分配10个缓冲区,是一个机器生成的,不能new实例,是一个抽象类
  • SecureRandom 提供一个更为健壮的随机数
  • 服务端要将客户端的信息接收到才可以进行分发,采取HashMap将数据存储
  • NIO解决多个客户端的连接的情况,减少CPU的上下文切换的工作量,传统IO的Socket无法解决这个问题,而且多个客户端连接会启用多个线程进行通信

2、java.nio 与 java.io

  • java.nio 在jdk1.4之后出现的包
  • java.nio 拥有3个核心概念: Selector、Channel 、Buffer,在java.nio中,我们是面向块(block)或是缓冲区(Buffer)
  • NIO的事件相当重要,用事件来判断请求与响应
  • NIO是可以存在输入流和输出流,在Buffer读到的数据也可以希尔Buffer当中(flip方法实现)状态翻转.
  • NIO的客户端与传统的Socket不同,只有一个线程进行通信,而传统的Socket编程会启动多个线程进行保证
  • configureBlocking(false); false表示设置非阻塞
  • 网络编程很多场景都是使用死循环进行实现

  • java.io 中最为核心的一个概念是流(Stream)面向流的编程,Stream是信息的载体,I/O要么是输出流,要么是输入流,不可能同时既是输入流又是输出流

3、NIO 3个核心概念关系图如:(重点)

  • [图解关系

  • NIO 3个核心
  • S-代表Selector(Thread)

  • C-代表Channel,

  • B-代表Buffer

  • 异步最核心的原理实现是事件理念

4、Java中有7种原生数据类型

  • Java中有7种原生数据类型都有各自对应的Buffer类型,如:IntBuffer,LongBuffer,CharBuffer等,但没有BooleanBuffer

5、Java NIO的Selector 的 processSelectedKey 中处理了三个事件, 分别是:

  • OP_READ, 可读事件, 即 Channel 中收到了新数据可供上层读取.
  • OP_WRITE, 可写事件, 即上层可以向 Channel 写入数据.
  • OP_CONNECT, 连接建立事件, 即 TCP 连接已经建立, Channel 处于 active 状态

6、Selector(重点)

  • Selector可以监听各种各样的事件(Event)事件当某事情发生时,连接已建立,数据已读取,读取完毕等都是事件
  • Selector通过提供者进行创建,通过系统或自定义提供者进行创建(openSelector)方法调用
  • SelectionKey 注册通道(标识事件)
  • key set (全集subset)
  • selected-key 子集(感兴趣)read与write
  • canceled-key 子集(不感兴趣)取消
  • selected-key是在进行通过添加到Selector,可以移除Set的remove方法,Inteator的remove方法
  • select方法是阻塞的
  • 每当一个Selector注册一个Channel都会SelectionKey
  • Selector一旦建立就可以对事件进行选择与注册,但不是epoll(轮询)
  • register注册到Selector对象上SelectionKey.OP_ACCEPT注册给订单ServerSocketChannel在Selector之上
  • SelectionKey.OP_ACCEPT连接事件,OP_READ读事件
  • isAcceptable月isReadble判断连接和可读数据
  • NIO的客户端的SelectionKey.OP_CONNECT连接,Executors.newSingleThreadExecutor单线程执行
  • Selector检测多个Channel,而一个线程可以被Selector控制,Channel的数据读与写由Buffer来完成

7、Channel(重点)

  • Channel 指的是可以向其写入数据或是从中读取数据的对象,类似java.io的流(Stream)
  • 与Stream不同的是,Channel是双向的,一个流只可能是InputStream或是OutputStream,Channel打开后则可以进行读取,写入或是读写
  • Channel一定是与Buffer一起进行使用实现NIO
  • Channel 没有Buffer是没有用武之地

8、Buffer(重点)

  • Buffer本身就是一块内存,底层实现实际上是一个数组,数据的读写是通过Buffer来实现的(重点),除了数组之外,Buffer还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程
  • 所有数据的读写都是通过Buffer来进行的,永远不会出现直接向Channel写入数据的情况,或是直接从Channel读取数据的情况(NIO)
  • Buffer是一种容器,有特定的原生类型
  • Buffer可以做到分类进行处理

9、关于NIO的Buffer 3个重要状态属性含义(重点

  • 图解关系
  • Buffer 3个重要状态
  • postion , limit , capacity (难点和重点)
  • 一个Buffer的capacity它包含的元素的数量,一个Buffer的capacity不可能为负数,并且永远不会变化
  • 一个Buffer的limit无法去写或读的,第一个元素的索引不可能是负数,不会超过capacity
  • 一个Buffer的position下一个元素索引的读或写不可能是负数,不会超过limit
  • 范围: capacity > limit > position
  • 范围: 0 <= mark <= position <= limit <= capacity

compact 方法
1、将所有未读的数据复制到Buffer起始位置处
2、将position 设为最后一个为读的元素的后面
3、将limit设为capacity
4、现在Buffer就准备好了,但是不会覆盖未读的数据

10、 clear ,flip ,rewind 方法(重点)

clear
1、clear 其实对数据重置,并没有清空数据(原理)
2、将limit值设为capacity
3、将postion值设为0

11、 直接缓冲区(重点)

  • 直接缓冲区,堆的缓冲,堆上的内存分配堆内上直接由JVM管理,堆外的内存分配,不由JVM管理,有操作系统进行管理
  • DirectByteBuffer直接缓冲,用了很多不开源的底层实现
  • DirectByteBuffer在java对,就不会存在一个所谓的数组,因为真实的数据已经在堆外存放者,所以用于数据读写,直接由操作系统来跟堆外的内存进行交互(少一次数据拷贝)称为零拷贝
  • MapperByteBuffe是一个直接缓冲区,是一个内存映射文件区域,用于内存映射的文件的内存本身在java堆面,换句话说,它是堆外内存,直接从内存修改,有操作系统操作
  • 拷贝不会产生GC,由JVM控制
DirectByteBuffer

12、 间接缓冲

  • 如果用了HeapByteBuffer实际上真正数据IO多了一个数据的拷贝过程,会把java的内存空间的字节数组的内容原封不动的拷贝到java模型内存之外的操作系统某块内存中,然后整个内存区字节跟我们IO设备进行交互
  • HeapByteBuffer

13、 中间缓冲区

  • 对于直接缓冲区Java的JVM就可以直接本地IO的操作,避免操作系统的原生的IO还复制内容到一个中间的缓冲区

14、 零拷贝

  • 零拷贝将IO操作时候不必你的Buffer的内容再拷贝一份放置系统的内存空间中,直接将你的堆上的分配的内存用于IO操作进行打交道,减少内存中转的过程,提供性能(重点

15、 通过NIO读取文件涉及到3个步骤

  • 1、从FileInputStream获取到FileChannel对象

  • 2、创建Buffer

  • 3、将数据从Channel读取到Buffer中

  • FileChannel关系图

16、 绝对方法和相对方法的含义

  • 相当方法:limit值与position值会在操作时被考虑到
  • 绝对方法:完成忽略掉limit值与position值

17、 ByteBuffer

  • ByteBuffer 放入是什么类型,取出来类型就是什么类型
  • ByteBuffer

18、 asReadOnlyBuffer 只读缓冲区

  • 只读Buffer,我们可以随时将一个普通的Buffer调用,asReadOnlyBuffer方法返回一个只读Buffer,但不能将一个只读Buffer转换为读写Buffer

19、 native关键字(难点)

  • native是本地的意思,通过JNI调用C / C++ 的底层代码

20、 堆上内存(难点)

  • new 处理的实例一定位于堆上(java内存模型)native不在java内存模型,称为堆外内存(难点
  • 堆上内存有JVM管控,堆外内存由操作系统进行管理,成员变量可以访问堆内/外内存,在Buffer有一个address变量直接可以访问直接缓冲

21、 Buffer的Scattering与Gathering(重点)

  • Scattering不仅传递一个Buffer,还可以传递一个Buffer的数组,其实将一个Channel里面的数据进行读取,如果不把第一个读完不会读第二个Channel的数据到Buffer数组
  • Gathering与Scattering刚好相反,它是写操作,一个一个地写到Buffer

22、 CPU上下文切换会影响性能

  • 系统的CPU不断切换的变化会影响线程的性能,而且查询设计使用太多线程会有弊端

23 推荐学习博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容