2011-08-03 7 views
1

受信した要求と応答を追跡するためのメカニズムとして参照カウントを使用するアプリケーションコンテナに取り組んでいます。参照カウントは、コンテナの正常なシャットダウンを可能にするために使用される。すなわち、if (refCount == 0) shutdown;は参照カウントが良いデザインです

参照カウントは、すべての要求およびペンディング応答に対してインクリメントされる。参照カウントは、アプリケーションが要求を受け入れると、アプリケーションが有効な応答を送信した後にのみ、デクリメントされます。 これは私の質問ですが、アプリケーション/コンテナが応答を送信したときに閉じられるRequestContextを保持するのと比較して、このシナリオで参照カウントは良い設計判断をしていますか?

ソフトウェアがJavaで実装されているので、私はJavaの他のオプションを探していて、http://weblogs.java.net/blog/2006/05/04/understanding-weak-referencesという記事を読んで、ReferenceQueueを利用しようとすると別のアプローチになると思いました。

+5

ここでは、「参照カウント」という用語を過負荷にしていると思います。新しい参照に要求オブジェクトを割り当てると、参照カウントが増加しません。私は "参照"がすべてここでの用語に属しているとは思わない。 –

答えて

1

実際にそれを行うのは本当にすてきな方法です。さらに、ThreadLocalを使用する必要があります(要求応答パイプラインが1つのスレッドで処理される場合)

基本的に要求を受け取ったとき。 WeakRefernceを指定してThreadLocalをリクエストオブジェクト(またはユーザIDなどのリクエストの属性)に設定します。次に、処理パイプライン内の任意の場所にオブジェクトget()を置くことができます。

要求を処理するためにThreadPoolワーカーを使用している場合は、そのオブジェクトの参照が存在しないようにスレッドのThreadLocalから弱参照オブジェクトを解除することを確認してください。リクエストごとに新しいスレッドを作成している場合、それを行う必要はありません。スレッドが終了すると、オブジェクトは自動的にreferenceQueueに返されます(ライブ参照がそのオブジェクトを指していないため)

+0

"さらに、ThreadLocal(要求応答パイプラインが単一のスレッドで処理される場合)を使用する必要があります。"コンテナがシングルスレッドであることを明確にしてください。そうであれば、ThreadLocalの使用は実際にはCPUサイクルの無駄です。 – alphazero

+0

ああ、絶対にそうではありません。私はマルチスレッドのコンテナについて話していました。私の言葉からの誤った意味を赦してください。 –

+0

わかりました。あなたを誤解して私を許してください! – alphazero

1

パフォーマンスヒットでそのカウンタを支払うことに注意してください。効果的には、リクエストを処理するために同時スレッドを使用している各リクエストIFFごとにメモリバリアが必要です。 (メモリバリア命令は通常、最大200命令までかかります)。

あなたの質問によれば、さらにカウンターが必要ではなく、アクティブな要求があるかどうかを示すバイナリフラグがあります。 requestsInProgressフラグ。あなたがフラグ値がfalseであるときにあなたが正常にシャットダウンするという考えがあります。

コンテナが主にネットワークエンドポイントを公開している場合など。 REST/HTTPでは、NIOを考慮して、単一のスレッドディスパッチ機構を使用して、コンテナの周辺でreq/repを線形化することを強くお勧めします。 (あなたはjava.util.concurrentで同時キューを使用して、N個の処理スレッドに出これらとファンをキューに入れることができます

[NIO subsystem] <-{poll}-[Selector(accept/read)/dispatch thread] => [Q:producer/consumer pattern 1:N] 
[NIO subystem] <-{poll}-[Selector(write)/responder thread] <= [Q:producer/consumer N:1] 

給付

あなたがディスパッチと応答のための同じスレッドを使用する場合は、何のメモリバリアが関与していません - 。?スレッドはコアに固定され、フラグはそのキャッシュライン専用になります。

ディスパッチキュー後

は要求:応答デキュー応答の後 インクリメントreq_in_progress

: 減少req_in_progress

は、シャットダウンの共有メモリの同期の必要性があるでしょうが、それはそのコストを負担するよりもはるかに優れていますあなたが実際にそれを必要とするときにそれを支払うだけで、それぞれの要求ごとに、

パフォーマンスがまったく問題でない場合は、カウンタにAtomicIntegerを使用してグローバルコンテキストに入れるのはなぜですか?

関連する問題