ネットティーチャネルハンドラーに状態を保持します
-
25-10-2019 - |
質問
NetTyドキュメントは、チャネルハンドラーのインスタンス変数を使用してチャネル状態を追跡することを示唆しています。揮発性変数を使用するか、他の同期技術を使用して、スレッド全体に一貫したビューがあることを保証する必要があることは言及していません。
たとえば、接続ごとにこのハンドラーを使用してください。
class Handler extends SimpleChannelUpstreamHandler {
int count = 0;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
++count;
}
}
ネットのスレッドプールからの多くの異なるスレッドがこの方法を呼び出すと予想しますが、同時にそうではありませんが、潜在的に一貫性のないビューを見る可能性があり、その結果、不正確なカウントが得られます。
これはそうですか?それとも、ネットの内部で何らかの同期が行われているのは、カウントフィールドへの書き込みをフラッシュする原因となっていますか?
解決
パイプラインに執行者がいなく、純粋にI/Oワーカースレッドでハンドラーを実行している場合、特定のパイプラインインスタンスが常に同じワーカースレッドから呼び戻されることを保証するため、あなたは元気です。
パイプラインに実行ハンドラーを追加する場合は、NettyのOrderedMemoryAwarEthReadPoolexecutorを使用している場合は大丈夫です。
非ネットスレッドからパイプラインにアクセスしている場合、またはパイプラインに非秩序化されたMemoryAwarethreadPoolexecutorがある場合は、同期する必要があります。
Nettyユーザーフォーラムアーカイブの次のスレッドを調べることをお勧めします。
他のヒント
ネットを作成するとき ChannelPipeline
追加する場合 同じ あなたのインスタンス Handler
すべてのチャネルには、はい、複数のスレッドがデータを読み取り/変更します。
の新しいインスタンスを作成する場合 Handler
以下に示すように、パイプラインのチャネルごとに安全です。 1つのスレッド のハンドラーにアクセスします パイプライン 一度に。
ChannelPipeline p = Channels.pipeline();
pipeline.addLast("handler", new Handler());
また、Nettyをご覧ください Channellocal, 、それはジャワのようです ThreadLocal
そして、あなたはチャネルごとに状態を設定することができます