Selector.select(timeout)x Selector.selectNow()

时间:2010-07-14 01:05:28

标签: java http nio nonblocking

我正在用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();
             //...
             }

任何人都知道此决定的影响/风险,或者如何使用带超时的选择器选择方法来减轻/消除尝试获取对象监视器的消耗时间?

感谢。

2 个答案:

答案 0 :(得分:1)

Selector api和sun的impl非常糟糕。

该文档允许您在一个选择器的select()上阻塞多个线程,但没有必要这样做。您应该只在一个selector.select()上阻止一个线程。

实际impl只在select()中执行syncrhonized(this)以实现线程安全。

就像过去同步过去的Vector和Hashtable一样。

他们应该简单地暴露低级原始非阻塞方法,而不是将它们包含在如此多的保姆抽象中 - 普通程序员不会使用选择器,那些做的人可以照顾好自己。

答案 1 :(得分:0)

睡觉而不是使用超时只会浪费更多时间 - 你总是在睡眠时间间隔睡觉,而如果有选择事件,你会在超时时提早醒来。

  

在某些情况下,Monitor状态会浪费   超过10个。

你是什么意思?