Java 在selector.selete()之后,selectedKeys()返回空
在使用JavaNIO时,我遇到了一些问题 我需要换一把钥匙。我发现这里有两种方法 首先通过调用key.interestOps完成: 但是,我遇到了非常棘手的线程安全问题:Java 在selector.selete()之后,selectedKeys()返回空,java,sockets,nio,Java,Sockets,Nio,在使用JavaNIO时,我遇到了一些问题 我需要换一把钥匙。我发现这里有两种方法 首先通过调用key.interestOps完成: 但是,我遇到了非常棘手的线程安全问题: key.interestOps(OP_WRITE); sl.select(); Iterator iter = sl.selectedKeys().iterator(); log(iter.toArray().length); // Sometimes, I got 0 here! 有趣的是,我有时在日志中得到0,但有时
key.interestOps(OP_WRITE);
sl.select();
Iterator iter = sl.selectedKeys().iterator();
log(iter.toArray().length); // Sometimes, I got 0 here!
有趣的是,我有时在日志中得到0,但有时效果很好。但在其他线程中并没有对密钥进行显式修改。我不明白2号线和3号线之间发生了什么
另一种方法是再次注册:
问题是新的返回键丢失了缓冲区:
key = sockChannel.register(selector, OP_WRITE);
key.attach(buf);
sockChannel.register(selector, OP_READ);
key.attachment();// nullExcetion here!
当然,这可以通过重新分配缓冲区来解决,但我相信事情会变得更好
有什么见解吗?我应该说Java NIO中的线程安全问题非常棘手。最好避免它,而不是找出它。这就是RoxJavaNIO教程的作者所倡导的理念,这是一个非常好的NIO新手教程。很多提示和原则都非常有用。我个人向所有想深入研究JavaNIO的人推荐本教程。阅读它,你会学到很多东西。第一个更好,因为你保留了密钥,但是没有“Iterator.toArray”这样的东西。真正的代码是什么?ROX NIO教程是垃圾。盖伊甚至不知道关闭频道会取消钥匙,他还发明了很多其他事情上不存在的困难。
key = sockChannel.register(selector, OP_WRITE);
key.attach(buf);
sockChannel.register(selector, OP_READ);
key.attachment();// nullExcetion here!