5

netty ドキュメントでは、ChannelHandlers でインスタンス変数を使用してチャネルの状態を追跡することを提案しています。スレッド全体で一貫したビューを確保するために、揮発性変数を使用したり、他の同期手法を使用したりする必要があることは言及されていません。

たとえば、このハンドラーを接続ごとに使用すると、次のようになります。

class Handler extends SimpleChannelUpstreamHandler {
        int count = 0;

        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
            ++count;
        }
}

netty スレッド プールからの多くの異なるスレッドがこのメソッドを呼び出していると予想されますが、同時にではなく、一貫性のないビューが表示される可能性があり、結果としてカウントが不正確になる可能性があります。

これは事実ですか?または、count フィールドへの書き込みがフラッシュされる原因となる netty 内で何らかの同期が行われていますか?

4

2 に答える 2

9

パイプラインにエグゼキュータがなく、ハンドラーを純粋にI / Oワーカースレッドで実行している場合、Nettyは、特定のパイプラインインスタンスが常に同じワーカースレッドからコールバックされることを保証しているので問題ありません。

パイプラインに実行ハンドラーを追加する場合は、NettyのOrderedMemoryAwareThreadPoolExecutorを使用していれば問題ありません。

Netty以外のスレッドからパイプラインにアクセスしている場合、またはパイプラインにOrderedMemoryAwareThreadPoolExecutorがない場合は、同期が必要です。

Nettyユーザーフォーラムアーカイブの次のスレッドを確認することをお勧めします。

http://netty.markmail.org/search/?q=Memory+visibility+in+handlers#query:Memory%20visibility%20in%20handlers+page:1+mid:cmtw5omcxbg67sho+state:results

http://netty.markmail.org/search/?q=Periodic%20TimerTask%20in#query:Periodic%20TimerTask%20in+page:2+mid:vwahepiois4eqwkp+state:results

于 2011-11-30T18:09:44.053 に答える
2

Netty を作成するときに、同じインスタンスをすべてのチャネルChannelPipelineに追加すると、はい、複数のスレッドがデータを読み取り/変更します。Handler

Handler以下に示すように、パイプラインでチャネルごとの新しいインスタンスを作成すると安全です。一度に1 つのスレッドのみがパイプライン内のハンドラーにアクセスします。

ChannelPipeline p = Channels.pipeline();
pipeline.addLast("handler", new Handler());

Netty ChannelLocalも見てください。これはJavaに似ThreadLocalており、チャネルごとに状態を設定できます

于 2011-11-29T17:58:24.783 に答える