我正在用Java实现一个非阻塞HTTP服务器,并决定使用纯Java NIO。我正在组合一个NIO Selector和一个小线程池来执行选择器指示的操作。
让系统选择默认选择器(在Linux 2.6 epoll和Mac OS Snow 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();
//...
}
任何人都知道此决定的影响/风险,或者如何使用带超时的选择器选择方法来减轻/消除尝试获取对象监视器的消耗时间?
感谢。
答案 0 :(得分:1)
Selector api和sun的impl非常糟糕。
该文档允许您在一个选择器的select()上阻塞多个线程,但没有必要这样做。您应该只在一个selector.select()上阻止一个线程。
实际impl只在select()中执行syncrhonized(this)
以实现线程安全。
就像过去同步过去的Vector和Hashtable一样。
他们应该简单地暴露低级原始非阻塞方法,而不是将它们包含在如此多的保姆抽象中 - 普通程序员不会使用选择器,那些做的人可以照顾好自己。
答案 1 :(得分:0)
睡觉而不是使用超时只会浪费更多时间 - 你总是在睡眠时间间隔睡觉,而如果有选择事件,你会在超时时提早醒来。
在某些情况下,Monitor状态会浪费 超过10个。
你是什么意思?