我正在用Java实现一个非阻塞HTTP服务器,并决定使用纯Java NIO。我将NIO选择器与一个小线程池相结合,以执行选择器指定的操作。
离开系统,选择默认选择器(在Linux 2.6 epoll和Mac Leo KQueue中进行了测试),使用Selector.select(TIMEOUT);,我将线程池置于监视器状态(等待获取监视器),而主线程(运行选择器事件循环)始终保持运行。在某些情况下,监视器状态(等待获取监视器的时间)浪费的时间超过10秒。
使用以下方法会导致主线程花费大部分时间处于休眠状态,睡眠时间更少(池化线程的监控状态几乎为零)和更好的吞吐量(每秒处理1k请求):
while (true) {
Thread.sleep(IOLoop.SELECT_TIMEOUT);
if (selector.selectNow() == 0)
continue;
Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
//...
}有谁知道这个决定的影响/风险,或者如何减轻/消除尝试使用带有超时的选择器选择方法获取对象监视器所花费的时间?
谢谢。
发布于 2010-07-15 01:53:32
选择器api和sun的impl太可怕了。
该文档允许您在一个选择器的select()上使用多个线程进行阻塞,但这样做毫无意义。在一个selector.select()上应该只有一个线程被阻塞。
实际的impl只是在syncrhonized(this) ()中执行选择,以实现线程安全。
它就像过去过度同步的Vector和Hashtable。
他们应该简单地公开低级原始非阻塞方法,而不是将它们包装在如此多的保姆抽象中-普通程序员不会使用选择器,而那些使用选择器的程序员可以自己照顾自己。
发布于 2010-07-14 09:31:26
睡眠而不是使用超时只会浪费更多的时间-你总是在睡眠间隔内睡眠,而使用超时如果有选择事件,你就会提早醒来。
在某些情况下,监视器状态浪费的时间超过10秒。
您这是什么意思?
https://stackoverflow.com/questions/3242685
复制相似问题