多线程非阻塞IO选择器

时间:2013-08-04 11:51:05

标签: java nio

具有非阻塞服务器,现在看起来像:

ServerSocketChannel server = ServerSocketChannel.open();
// ... Many stuff like initialise selector, load world, etc
while(server.isOpen())
{
    selector.select();
    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
    while(iterator.hasNext())
    {
        SelectionKey key = iterator.next();
        switch(key.interestOps())
        {
            case SelectionKey.OP_ACCEPT:
                // .... Accepting, register selector, packet handler etc
                break;
            case SelectionKey.OP_READ:
                // .... Read-write stuff
                break;
        }
        iterator.remove();
    }
}

我需要例如1个线程处理100个连接。其他100个连接处理另一个线程。我尝试用这段代码来做:

public class ConnectionsHandler implements Runnable
{
    private Selector selector;// For each thread gets its own selector

    @Override public void run()
    {
        while(Server.server.isOpen())
        {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while(iterator.hasNext())
            {
                SelectionKey key = iterator.next();
                // .... Read-write stuff
                iterator.remove()
            }
        }
    }
}

但是第一次接受连接后的两个线程都冻结了......没有任何异常抛出,它只是冻结。

1 个答案:

答案 0 :(得分:1)

register()是一个阻塞操作,因此是select()。如果getMostFreeSelector()返回另一个选择器并且它当时在select()中,则register()将阻塞,直到选择器唤醒。您可以调用selector.wakeup()来解决此问题,或者始终注册到当前选择器,但我会质疑整个架构。除非你有成千上万的连接,否则在第二个选择器和线程中没什么意义。

还请注意我上面关于switch语句的评论。

相关问题