一. 同步, 异步 & 阻塞, 非阻塞
概念
同步和异步其实指的是,请求发起方对消息结果的获取是主动发起的,还是等被动通知的。
- 如果是请求方主动发起的,一直在等待应答结果(同步阻塞)
- 如果是结果由服务方通知的,也就是请求方发出请求后,要么在一直等待通知(异步阻塞), 要么就先去干自己的事了(异步非阻塞)
调用了一个函数之后,在等待这个函数返回结果之前,当前的线程是处于挂起状态,还是运行状态:
- 如果是挂起状态,就意味着当前线程什么都不能干,就等着获取结果,这就叫同步阻塞,
- 如果仍然是运行状态,就意味当前线程是可以的继续处理其他任务,但要时不时的去看下是否有结果了,这就是同步非阻塞。
形象的例子
故事:老王烧开水。
出场人物:老王,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
老王想了想,有好几种等待方式
1、老王用水壶煮水,并且站在那里,不管水开没开,每隔一定时间看看水开了没 ———-同步阻塞
老王想了想,这种方法不够聪明。
2、老王还是用水壶煮水,不再傻傻的站在那里看水开,跑去寝室上网,但是还是会每隔一段时间过来看看水开了没有,水没有开就走人。 ———-同步非阻塞
老王想了想,现在的方法聪明了些,但是还是不够好。
3、老王这次使用高大上的响水壶来煮水,站在那里,但是不会再每隔一段时间去看水开,而是等水开了,水壶会自动的通知他。 ———-异步阻塞
老王想了想,不会呀,既然水壶可以通知我,那我为什么还要傻傻的站在那里等呢,嗯,得换个方法。
4、老王还是使用响水壶煮水,跑到客厅上网去,等着响水壶自己把水煮熟了以后通知他。 ———-异步非阻塞
老王豁然,这下感觉轻松了很多。
二. NIO 中一些重要概念
Java IO 模型
BIO–同步阻塞:
JDK1.4 以前我们使用的都是 BIO
阻塞到我们的读写方法,阻塞到线程来提高并发性能,但是效果不是很好
NIO–同步非阻塞:(New IO)
JDK1.4 Linux 多路复用技术(select 模式)实现 IO 事件的轮询方式:同步 非阻塞的模式,这种方式目前是主流的网络通信模式
Mina 和 Netty
– 网络通信框架,比自己写 NIO 要容易些,并且代码可读性更好
AIO–异步非阻塞 IO:
JDK1.7(NIO2)真正的异步非阻塞 IO(基于 linux 的 epoll 模式)AIO 目 前使用的还比较少
通道 channel & 缓冲区 buffer
1. 通道 channel
关键词: 模拟流, 打开的连接, 双向可读写, 线程安全, 只能通过缓冲区操作
类型
- FileChannel:从文件中读写数据;
- DatagramChannel:通过 UDP 读写网络中数据;
- SocketChannel:通过 TCP 读写网络中数据;
- ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
2. 缓冲区 buffer
不能直接对通道进行读写数据,而是要先经过缓冲区。
缓冲区实质上是一个数组, 提供了对数据的结构化访问。
类型:
- ByteBuffer
- CharBuffer
- ShortBuffer
- IntBuffer
- LongBuffer
- FloatBuffer
- DoubleBuffer
关键词:
- capacity:最大容量;
- position:当前已经读写的字节数;
- limit:还可以读写的字节数。
三. 代码实例
Server
1 | package com.rox.nio; |
Client
1 | package com.rox.nio; |