在selector.selete()之后,selectedKeys()返回空

时间:2013-09-05 13:11:07

标签: java sockets nio

使用Java NIO时,我遇到了一些问题。

我需要更改interestOps key。我发现这里有两种方法可以做到。

首先是通过调用key.interestOps()

来完成的
key.interestOps(OP_READ)

但是我以这种方式遇到了非常棘手的线程安全问题:

key.interestOps(OP_WRITE);
sl.select();  
Iterator iter = sl.selectedKeys().iterator();
log(iter.toArray().length); // Sometimes, I got 0 here!

有趣的是我有时会在日志中得到0(但有时它效果很好)。但是在其他线程中没有明确修改密钥。我无法理解line2line3之间发生了什么。

另一种方式是再次register

问题是新的返回key丢失了他的缓冲区:

key = sockChannel.register(selector, OP_WRITE);
key.attach(buf);
sockChannel.register(selector, OP_READ);
key.attachment();// nullExcetion here!

当然这可以通过重新分配缓冲区来解决,但我确信事情会更好。

任何见解?

1 个答案:

答案 0 :(得分:0)

我应该说Java NIO中的线程安全问题太棘手了。最好避免它而不是解决它。这是 Rox Java NIO Tutorial http://rox-xmlrpc.sourceforge.net/niotut/的作者所倡导的哲学,这是一本关于NIO绿色动手的优秀教程。很多提示和原则都非常有用。我个人会向每个想要深入了解Java NIO的人推荐本教程。阅读它,你可以学到很多东西。