2

複数のクライアント間で一貫した状態を維持するためにRMIを使用するGUIアプリケーションを作成する必要があります。

RMI呼び出しはブロックされるため、GUIスレッドとは別のスレッドに配置します。GUIスレッドとの間で情報をプッシュするために、私の最初の考えは同期バッファーを使用することでした。

しかし、Bufferで同期されたメソッドを呼び出すと、GUIがフリーズします。同期キーワードを使用しない場合、バッファはスレッドセーフではありません。

Javaドキュメントから:

同じオブジェクトで同期されたメソッドを2回呼び出して、インターリーブすることはできません。1つのスレッドがオブジェクトの同期メソッドを実行している場合、同じオブジェクトブロックの同期メソッドを呼び出す他のすべてのスレッドは、最初のスレッドがオブジェクトで完了するまで実行を一時停止します。

バッファスレッドを安全にし、GUIをフリーズさせない他の方法はありますか?

4

3 に答える 3

3

1 つのアプローチは、モデル – ビュー – コントローラー パターンを使用しビューからモデル データを分離 することです。最後の例では、モデルはバックグラウンド スレッドで進化し、ビューは を使用して定期的に更新されます。ここに示されているは、代替手段です。javax.swing.TimerSwingWorker

于 2012-08-27T02:39:03.737 に答える
2

いくつかのアプローチを試すことができます。

UI に変更を通知するために使用できる RMI/read スレッドからイベントを発生させることができます。EDT で UI のみを更新するようにしてください。

SwingWorkerを使用して RMI リクエストをバックグラウンドで処理し、publish`process` メソッドを使用して結果をクライアントに同期させることができます。

于 2012-08-27T02:40:32.680 に答える
2

のオブジェクトのいずれかがうまくいくかどうかを確認してくださいjava.util.concurrent。よりきめ細かい制御が可能ですsynchronized

たとえば、 a でできることは次のSemaphoreとおりです。

一部の共有クラスで

public class Shared {
  public final Semaphore mutex = new Semaphore(1);
}

RMI スレッド内

// synchronizing with other clients...
// now we're at the critical section.  Block until we have the lock
Shared.mutex.acquireUninterruptibly();
// update state
Shared.mutex.release();
// critical section over.  Schedule an update on the GUI thread.

GUI スレッドで

// if the critical section is free, check for updated state.  Else, just wait
if (Shared.mutex.tryAcquire())  {
   try {
     // read state and update GUI
   } finally {
     Shared.mutex.release();
   }
}

ここでは、GUI スレッドがすべての更新を確認できるとは限りませんが、RMI スレッドが常に状態を更新していない場合は機能するはずです。

于 2012-08-27T04:23:06.240 に答える