具有非阻塞服务器,现在看起来像:
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()
}
}
}
}
但是第一次接受连接后的两个线程都冻结了......没有任何异常抛出,它只是冻结。
答案 0 :(得分:1)
register()是一个阻塞操作,因此是select()。如果getMostFreeSelector()返回另一个选择器并且它当时在select()中,则register()将阻塞,直到选择器唤醒。您可以调用selector.wakeup()来解决此问题,或者始终注册到当前选择器,但我会质疑整个架构。除非你有成千上万的连接,否则在第二个选择器和线程中没什么意义。
还请注意我上面关于switch语句的评论。