多路复用 对比 线程池 伪异步的优点:
使用线程池模型:
假设机器A可以开1000个线程,那最多就是1000个连接。
因为网络IO较慢且需要阻塞,此时可能有900个线程处于阻塞在网络IO处的状态。
也就是只有100个线程在干别的事情。
这样对整个机器A的所有资源都是浪费。
使用多路复用以后, 网络IO阻塞不在占用独有的线程。同样是机器A,
做实际事情的线程数可能可以开到1000, 实际做事的效率就<strong>可能</strong>要比之前高。
这里为啥是可能呢而非一定呢?
比如机器A装的是db, 这个db的100个线程就跑到了 磁盘IO瓶颈, 这时在接受新的任务(增加线程数)就不会增加效率,反而会降低效率。
下图是java中NIO的使用的示意:
当向Selector注册Channel时,register()方法会返回一个SelectionKey对象
这个对象很重要,它包含了
interest集合
ready集合
Channel 生成这个key 时, 注册的channel
Selector 生成这个key 时, 被注册的Selector
附加的对象(可选)
SelectionKey key = keyIterator.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}
使用线程池模型:
假设机器A可以开1000个线程,那最多就是1000个连接。
因为网络IO较慢且需要阻塞,此时可能有900个线程处于阻塞在网络IO处的状态。
也就是只有100个线程在干别的事情。
这样对整个机器A的所有资源都是浪费。
使用多路复用以后, 网络IO阻塞不在占用独有的线程。同样是机器A,
做实际事情的线程数可能可以开到1000, 实际做事的效率就<strong>可能</strong>要比之前高。
这里为啥是可能呢而非一定呢?
比如机器A装的是db, 这个db的100个线程就跑到了 磁盘IO瓶颈, 这时在接受新的任务(增加线程数)就不会增加效率,反而会降低效率。
下图是java中NIO的使用的示意:
当向Selector注册Channel时,register()方法会返回一个SelectionKey对象
这个对象很重要,它包含了
interest集合
ready集合
Channel 生成这个key 时, 注册的channel
Selector 生成这个key 时, 被注册的Selector
附加的对象(可选)
SelectionKey key = keyIterator.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}