Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Selector.select(超时)x Selector.selectNow()_Java_Http_Nio_Nonblocking - Fatal编程技术网

Java Selector.select(超时)x Selector.selectNow()

Java Selector.select(超时)x Selector.selectNow(),java,http,nio,nonblocking,Java,Http,Nio,Nonblocking,我正在用Java实现一个非阻塞HTTP服务器,并决定使用纯JavaNIO。我将NIO选择器与一个小线程池相结合,以执行选择器指示的操作 让系统选择默认选择器(在和Mac OS Snow Leo中测试)并使用选择器。选择(超时)我使线程池处于监视器状态(等待获取监视器),而主线程(运行选择器事件循环)始终保持运行。在某些情况下,监视器状态(等待获取监视器的时间)浪费超过10秒 使用以下方法会使主线程花费大部分时间睡眠,更少(池线程几乎没有监视状态)和更好的吞吐量(每秒处理1k个请求): while

我正在用Java实现一个非阻塞HTTP服务器,并决定使用纯JavaNIO。我将NIO选择器与一个小线程池相结合,以执行选择器指示的操作

让系统选择默认选择器(在和Mac OS Snow Leo中测试)并使用
选择器。选择(超时)我使线程池处于监视器状态(等待获取监视器),而主线程(运行选择器事件循环)始终保持运行。在某些情况下,监视器状态(等待获取监视器的时间)浪费超过10秒

使用以下方法会使主线程花费大部分时间睡眠,更少(池线程几乎没有监视状态)和更好的吞吐量(每秒处理1k个请求):

while(true){
休眠(IOLoop.SELECT\u TIMEOUT);
if(selector.selectNow()==0)
继续;
迭代器iter=selector.selectedKeys().Iterator();
//...
}
是否有人知道此决策的影响/风险,或者如何减轻/消除使用带超时的选择器选择方法获取对象监视器所花费的时间


谢谢。

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

在某些情况下,监管者会浪费时间 超过10秒


你这是什么意思?

睡眠而不是使用超时只会浪费更多的时间-你总是在睡眠时间间隔内睡觉,而如果有选择事件,超时会让你早起

在某些情况下,监管者会浪费时间 超过10秒


你这是什么意思?

选择器api和sun的impl都很可怕

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

而实际的impl只是在select()中进行了
同步(this)
,以实现线程安全

这就像过去过度同步的向量和哈希表


他们应该简单地公开低级的原始非阻塞方法,而不必将它们包装在如此多的保姆式抽象中——一般程序员不会使用选择器,而那些使用选择器的人可以自己照顾自己。

选择器api和sun的impl太可怕了

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

而实际的impl只是在select()中进行了
同步(this)
,以实现线程安全

这就像过去过度同步的向量和哈希表


他们应该简单地公开低级的原始非阻塞方法,而不必将它们包装在如此多的保姆式抽象中——一般程序员不会使用选择器,而那些使用选择器的人可以自己照顾自己。

yap EJP,现在我必须等待一段固定的时间。奇怪的是,对于获取池中线程的监视器来说,吞吐量更好,而且没有CanceledKeyException/过多的时间浪费。更新问题以澄清监视器。CancelledKeyException表示您正在处理已取消的密钥,通常是因为通道已关闭。您可以通过在选择器处理循环的头部测试key.isValid()来解决这个问题。坦率地说,您似乎对一些代码理解不透彻,并且采用了糟糕的技术,而不是正确的解决方案。奇怪的是,对于获取池中线程的监视器来说,吞吐量更好,而且没有CanceledKeyException/过多的时间浪费。更新问题以澄清监视器。CancelledKeyException表示您正在处理已取消的密钥,通常是因为通道已关闭。您可以通过在选择器处理循环的头部测试key.isValid()来解决这个问题。坦率地说,您似乎对一些代码理解不透彻,并且采用了糟糕的技术而不是正确的解决方案。您会推荐什么?(我们不能考虑米娜、荨麻、灰熊等)。谢谢。每个选择器应该有一个线程。该线程执行select(),然后从所选通道读取数据。在您的HTTP请求中,解析数据也可以在同一线程中执行。这听起来像是单线程编程,如果您只有一个CPU,那么它的性能会很好。如果您有N个CPU,那么您可以有N个选择器,每个选择器都有一个上面描述的线程。它需要一些变通方法来防止线程访问单线程选择器。例如,在实际向线程分派事件之前,取消键并执行下一次选择。我也会尝试你的方法。谢谢如果另一个线程试图在执行select(timout)的选择器上注册新的/现有的频道,我仍然面临一些问题;第二个线程保持阻塞状态,直到这段时间过去。甚至在注册之前调用selector.wakeup()。您的方法应该很快得到测试。解决此问题的一种方法是为select()使用变量timeout。我正在使用线程池来处理selectedKeys中的事件。如果池中有任何正在运行的线程,则超时是它所能达到的最小值(1ms或切换为selectNow而不是select(超时))。虽然看起来不太好,但效果很好。你有什么建议吗?(我们不能考虑米娜、荨麻、灰熊等)。谢谢。每个选择器应该有一个线程。该线程执行select(),然后从所选通道读取数据。在您的HTTP请求中,解析数据也可以在同一线程中执行。这听起来像是单线程编程,如果你只有一个
    while (true) {
        Thread.sleep(IOLoop.SELECT_TIMEOUT);
        if (selector.selectNow() == 0)
            continue;

        Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
             //...
             }