使用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(但有时它效果很好)。但是在其他线程中没有明确修改密钥。我无法理解line2
和line3
之间发生了什么。
另一种方式是再次register
:
问题是新的返回key
丢失了他的缓冲区:
key = sockChannel.register(selector, OP_WRITE);
key.attach(buf);
sockChannel.register(selector, OP_READ);
key.attachment();// nullExcetion here!
当然这可以通过重新分配缓冲区来解决,但我确信事情会更好。
任何见解?
答案 0 :(得分:0)
我应该说Java NIO中的线程安全问题太棘手了。最好避免它而不是解决它。这是 Rox Java NIO Tutorial http://rox-xmlrpc.sourceforge.net/niotut/的作者所倡导的哲学,这是一本关于NIO绿色动手的优秀教程。很多提示和原则都非常有用。我个人会向每个想要深入了解Java NIO的人推荐本教程。阅读它,你可以学到很多东西。