-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathNIO.java
More file actions
98 lines (77 loc) · 4.04 KB
/
NIO.java
File metadata and controls
98 lines (77 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
-------------------------------
Netty-IO的区别 |
-------------------------------
# JDK1.4的的东西
# BIO 和 NIO的区别
阻塞 :程序在获取网络数据的时候,如果网络数据传输慢,那么程序就会一直等待下去.直到传输完毕
非阻塞 :程序可以直接获取已经准备就绪的数据,无需等待
'BIO为同步阻塞,NIO为同步非阻塞,NIO并没有实现异步',JDK1.7以后,升级了NIO包,支持异步非阻塞通信模型-NIO2.0(AIO)
同步和异步 :同步和异步一般是面向操作系统与程序对于IO操作的层面上来区别的
同步:程序直接参数IO读写,并且程序会阻塞到某方法,直到数据准备就绪,或者采用轮询的策略实时检查数据的就绪状态,如果数据准备就绪则读取数据、
异步:所有的IO交给操作系统去处理,与程序没关系.程序不用关心读写.操作系统完成了IO后,会通知程序,程序只需要拿走数据就OK
同步说的是Servlet服务器端的执行方式
阻塞说的是具体的技术,接收数据的方法(IO,NIO)
# 阻塞/非阻塞
* 阻塞,意思是程序,收数据的时候.是要一直等着.啥也做不了,直到数据传完
* 非阻塞,意思是.有个缓冲区.收的时候,我不用一直等着.可以做点其他有意思的事情,缓冲区里面有数据了?我就处理一点
# 异步/同步
* 跟操作系统有关,异步就是.收数据这活儿操作系统给我干了.我不管,就有时间搞其他的.操作系统弄完了.通知我OK
* 同步就是,直接我亲自上.
# NIO原理
* 事件的轮询,多路复用技术(Select模式),轮询交给一个单独的线程来完成.当是数据准备OK后通知读写线程来进行读写操作.那么在数据未准备OK之前,读写线程可以完成其他的事情
* 传统BIO中,读写线程需要自己等着数据准备OK,进行读写
# 学习网站
* http://ifeve.com/overview/
* http://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html
* http://watchmen.cn/portal.php?mod=view&aid=509
* http://www.iteye.com/magazines/132-Java-NIO
* http://www.importnew.com/19816.html
BIO - 同步阻塞
NIO - 同步非阻塞(JDK1.4)
AIO - 异步非阻塞(JDK1.7)
-------------------------------
Netty-NIO |
-------------------------------
# NIO 有人叫做 New IO 或者 Non-block IO (非阻塞),最好还是以后者的理解比较恰当
# 学习NIO需要明确几个概念
Buffer
* 缓冲区
* NIO 中核心的概念,传统是直接IO数据,要么写要么读.NIO提供了一个缓冲区的概念
Channel
* 管道/通道
Selector
* 选择器/多路复用器
-------------------------------
Netty-Channel |
-------------------------------
# 通道,跟自来水管道没啥区别.网络数据通过 Channel 读取/写入,'与传统流不同的是,它双向的',而流要么是读流,要么是写流
# 最叼的是,这个通道可以同时的进行读/写
# 最关键的是,可以和多路复用器结合起来,有多种状态位,方便多路复用器去识别.
# 事实上,通道分为两大类
1,SelectableChannel 网络读写
* DatagramChannel //UDP
* SocketChannel //TCP
* ServerSocketChannel //服务器端对象
2,FileChannel 文件操作
-------------------------------
Netty-Selector |
-------------------------------
# 多路复用器,它是NIO编程的基础,非常重要.多路复用器,提供'选择已经就绪的任务的能力'
# 简单说,Selector 会不断的轮询,注册在其上的通道 Channel,如果某个通道发生了读写操作.这个通道就处于就绪状态.会被 Selector 轮询出来,然后通过 SelectionKey 可以 取得就绪的 Channel 集合,从而进行后续的操作
# 一个多路复用器,可以负责成千上万的 Channel 通道,没有上限.这也是JDK使用 epoll代替了传统 Select实现,获取连接句柄没有限制,意味着我们只需要一个线程负责 Selector 的轮询.就可以接入成千上万的客户端,这就是JDK NIO库的巨大进步
# Selector 线程就类似于一个管理者(Master),管理成千万的通道,然后轮询出哪个通道已经准备好.通知CPU执行I/O操作
# Selector 模式:当IO事件(管道)注册到选择器后,Selector 会分配给每个管道一个 key 值,标签.Selector 轮询注册的管道,当管道就绪后, select就会识别,通过key值来找到对应的管道.进行相关数据处理操作.(写入,或者读到缓冲区)
# 每个管道都会对选择器注册不同的事件状态,以便选择器查找
SelectionKey.OP_ACCEPT //用于套接字接受操作的操作集位。
SelectionKey.OP_CONNECT //用于套接字连接操作的操作集位。
SelectionKey.OP_READ //用于读取操作的操作集位。
SelectionKey.OP_WRITE //用于写入操作的操作集位。
-------------------------------
Netty-总结 |
-------------------------------
# Buffer
* 新建总是要执行 clear(); 比较好
* 如果是从 Buffer 中读取数据,要先记得复位,然后再进行读取.
* 如果是从 Buffer 中读取数据那么要用 while(buf.hasRemaining()) 循环,有可能数据一次性没读取完
# Channel
* 如果是读取 Channel 中的数据,非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的 int 返回值