0

クライアント ログイン タスクを検出すると、メッセージ処理タスクは NEW メッセージの処理を停止する必要があります。ただし、メッセージ プロセッサは、一時停止する前に処理していたタスクを完了する必要があります。これは基本的に、クライアント ログイン タスクが、続行する前にメッセージ プロセッサに呼吸スペースを与える (それ自体を待機する) 必要があることを意味します。というわけでシナリオはこれ

1) message-processing-task is processing messages from a queue (one at a time)
2) It detects a client-login in the middle of processing a message
3) message-processing-task should complete processing the message before it waits for the client-login-task to complete. This is where the client-login-task must wait.
4) client-login-task complete and signals message-processing-task
5) message-processing-task goes about its business.

私の質問は、異なるパスを実行しているが、お互いに待機する必要があるこれら 2 つのスレッド間に既製のシンクロナイザーはありますか? 私の理解では、Cyclic Barrier、Semaphore、CountDownLatch は、同じ実行パスにあるスレッド間で同期します。

編集-単一のメッセージ処理スレッドがあります。ただし、複数のログイン スレッドが存在する場合があります。

私が考えている解決策は、再入可能ロックを使用することです。したがって、各メッセージを処理する前に、ロックが取得され、メッセージ プロセッサが進行中のクライアント ログインがあるかどうかがチェックされます。AtomicInteger は、進行中のログイン リクエストの数を教えてくれます。進行中のログイン要求が複数ある場合、通知プロセッサはロック状態で待機します。通知プロセッサが作業を再開するように通知される条件は、AtomicInteger カウントが 0 になる必要があることです。解決策に関する唯一の注意点は、メッセージが処理されており、ログイン要求がその途中で発生した場合です。ログイン スレッドは待機しません。ここで、メッセージ プロセッサがメッセージを処理したときに解放する必要がある、クライアント ログインの別のロックが必要になります。これにより、ソリューションが非常に複雑になり、この不必要な複雑さを避けたいと思います。任意の提案をいただければ幸いです。

4

2 に答える 2

1

Semaphore(1 permit, fairness true) を使用した単純なアプローチは、ログイン/メッセージ処理タスク間で 1 つを共有することです。メッセージ処理スレッドがタスクの途中にある場合、ログイン タスクが処理される前にスレッドが終了します (公平性により、ログイン タスクが直後に実行されることが保証されます)。

複数のメッセージ処理スレッドがある場合、このアプローチは機能しません。

于 2014-11-28T08:24:42.660 に答える
1

これを正しく拾ったかどうかはわかりませんが、ThreadPoolExecutor単一のスレッドで a を使用しPriorityBlockingQueue、それに a を渡します。すべてのタスクはそのキューに送られ、ログイン タスクの優先度が高くなるため、すべてのmessage-processingタスクがタスクの前に処理されます。

またmessage-processing-task、進行中の場合は、開始前に完了client-login-tasksします。それが必要ですか?

于 2014-11-28T09:49:56.397 に答える