Readiness Selection 倒底有什么好处?

Readiness Selection倒底好在哪里? 有人说它可以实现一个线程服务多个并发的请求,可以省线程云云。

这种囫囵吞枣的说法让人非常迷惑。在经过较为细致的学习之后,我试着来澄清一下。

首先,凡是对性能有点高的应用,想通过一个线程来服务多个并发请求分明就是天方夜谈。即使你用了Readiness Selection,你的Selector也来不及处理那么多Readiness通知。
正确的做法是,使用单线程来做监听Readiness通知,然后把事件委派给子线程处理

到这里,你也许会像我当时一样迷惑:
普通的I/O模式已经可以实现监听连接和处理数据的分离了,主线程accept(), 子线程再对刚建立起的socket读写数据;
有必要再用Readiness Selection么? 

答案是:
虽然新旧模式都实现了监听和处理的分离,但是旧模式中分离的并不彻底,从而产生一些阻塞。 在旧模式中,子线程拿到socket后调用socket.getInputStream()读数据时很有可能阻塞,因为此时socket可能还没数据让你读;在没让你读之前你就读,结果你只能等待。线程是宝贵的资源,让它去干等而不去干该干的事情(比如另外一个socket准备好了可以读了),不是浪费是什么?

而在新模式中,主线程收到acceptable通知时并没有必要立即启动子线程,它完全可以等到收到readable通知时才启动子线程或者把任务分配到子线程池中;被指派的子线程可以立即干活,不必再等待了。 线程的利用率很高,不存在浪费,系统总体的吞吐率也会比较好。

总结一下, 高并发下,使用Readiness Selection仍需要配置使用多线程来处理数据;而Readniess Selection之所以高效,是因为它直到数据真正可读或可写时才会将任务指派给处理线程将让后者立即处理,而不必像旧模式那样早早地把子线程阻塞了。

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.