1

Java NIO を使用しているときに、いくつか問題が発生しました。

のを変更する必要がinterestOpsありkeyます。ここには2つの方法があることがわかりました。

最初は、次の呼び出しによって行われ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!

もちろん、これはバッファを再割り当てすることで修正できますが、状況は改善されると確信しています。

洞察はありますか?

4

1 に答える 1

-1

Java NIO のスレッド セーフの問題は非常にトリッキーだと言わざるを得ません。それを理解するのではなく、それを避ける方が良いです。これは、 Rox Java NIO チュートリアル http://rox-xmlrpc.sourceforge.net/niotut/の著者によって提唱された哲学であり、 NIO の未経験者向けの優れたチュートリアルです。多くのヒントと原則は非常に役立ちます。個人的には、Java NIO を掘り下げたいすべての人にこのチュートリアルをお勧めします。それを読んで、多くのことを学ぶことができます。

于 2013-09-08T12:16:14.800 に答える