在使用Java NIO时,我遇到了一些问题。
我需要更改key
的interestOps
。我发现这里有两种方法可以做到这一点。
首先是通过调用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 (但有时它工作得很好)。但其他线程中没有显式修改key。我无法理解 line2
和 line3
之间发生了什么。
另一种方法是再次注册
:
问题是新的返回key
丢失了他的缓冲区:
key = sockChannel.register(selector, OP_WRITE);
key.attach(buf);
sockChannel.register(selector, OP_READ);
key.attachment();// nullExcetion here!
当然,这可以通过重新分配缓冲区来解决,但我确信事情会更好。
有什么见解吗?
最佳答案
我应该说Java NIO 中的线程安全问题非常棘手。最好避免它,而不是弄清楚它。这就是《Rox Java NIO 教程》作者 http://rox-xmlrpc.sourceforge.net/niotut/ 所倡导的理念。 ,这是 NIO 新手的绝佳教程。很多技巧和原则非常有用。我个人向所有想要深入研究 Java NIO 的人推荐本教程。阅读它,你可以学到很多东西。
关于java - 在selector.selete()之后,selectedKeys()返回空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18637296/