1

趣味でバナナグラムのシミュレーションを書いています。同時実行を使用したいのですが、その方法がよくわかりません。

クラスにメインメソッドがありGameます。各プレーヤー スレッドは、解決策に向かって機能します。特定の時点で、プレーヤーは「剥がれます」。この操作中、すべてのプレイヤーに新しい牌が配られます。プレーヤー スレッドの 1 つがスレッドに通知する必要がありGameます。

擬似コードは次のようになります。

while (no player has reported they are finished) {
      if (player reports it is time to peel) {
           everyone peel 
      }
      everyone work towards completion of puzzle
}

これを Java で実装するにはどうすればよいですか? (必ずしも完全に肉付けされたソリューションを探しているわけではありません。正しい方向に向けてください。) オブジェクト間の通知をどのように処理したいですか?

明確にするために:これはユーザー インタラクション ゲームではありません。さまざまなアルゴリズムを試して、どのアルゴリズムが問題を最も速く解決できるかを確認したいだけです。どちらかといえば、「ゲーム」とは、アルゴリズムを作成し、それをプラグインして、それがどのように機能するかを確認することです。

4

3 に答える 3

5

これはCyclic Barrierを使用するのに適した場所です。

基本的に、Cyclic Barrier を使用すると、スレッドが何らかの作業を行い、すべてのスレッドがすべて同じポイントに到達するまで待機し、その後、各スレッドが再び開始されます。

そのため、各プレイヤーに皮をむかせてから、CyclicBarrier.await() を呼び出すことができます。すべてのスレッドは、それぞれがそのポイントに到達するまで待機します。これはあなたが望むもののようです。

(また、これには並行性が本当に必要ないことは明らかです:)

于 2009-12-26T07:44:32.083 に答える
1

Observer パターンが適切かもしれません。誰もがメイン スレッドに登録して、ピール イベントに関する通知を受け取ります。1 人がピーリングの時間だと報告すると、メイン スレッドに通知し、メイン スレッドは登録されているすべてのスレッドに通知します。通知は、メソッド呼び出しを介してメインスレッドによって設定され、ゲームループの各反復でプレーヤースレッドによってチェックされる特別なスレッドローカル変数 (各プレーヤースレッドには独自のものがあります) を介して行うことができます。

編集: Java でのマルチスレッド方式でのオブザーバー パターンの実装について詳しく説明している記事へのリンクを次に示します。 http://www.javaworld.com/jw-03-1999/jw-03-toolbox.html

于 2009-12-26T06:44:25.200 に答える
1

プロセスが正確に何であるかによっては、スレッド化を行う必要がない場合があります (これは、大きな子供たちがどれほどクールで楽しいものであっても、可能な限り避けたいものです)。

この問題に対処する 1 つの方法は、イベント キューを設定することです。

疑似コードで

 enum EVENTTYPES = {PEEL=0, WORK=1};
 struct Event = {
     int eventType;
     int* data;
 }

 filoQueue eventQueue;

 array sQuidPlayers = [new Squid(), new Squid(), new Squid()];
 void eventLoop () {
      int player;
      for each player in sQuidPlayers {
          eventQueue.push(new Event(EVENTTYPES.WORK, player.id));
      }

      for each event in eventQueue {
           game.doEvent(event)
      }

 }

したがって、ここでは、操作したいフレーム レートに関係なく、イベント ループを毎秒 25 回、30 回、または 60 回実行します。そのためにタイマーを使用します(Javaのどこかにあると確信しています)

次に、doEvent は、対応するプレーヤー インスタンスで対応するメソッドを検索しようとします。Squid クラスの work メソッドは、いくつかの小さな作業を実行してから停止し、ループ内で次の時間を待ちます。配列内の各 Squid は、自分の小さな仕事をする番になります。作業メソッドは、PEEL イベントをイベント キューに入れることができます (MAY)。その時点で、次回のループで、対応するピール メソッドが呼び出される場合があります。おそらく、一部の中心的なゲーム クラスで、ピール イベントを発生させたプレイヤーの ID を使用します。これらのイベントをディスパッチする方法のロジックをそこの doEvent メソッドに入れます。次に、doEvent はオブジェクトを各イベント レシーバーに渡すことができるため、レシーバーは独自のイベント オブジェクトをキューに入れ、次回のループで実行することができます。(または、「イベントごとに」

秘訣は、長時間実行されている作業を小さな作業に分割する方法を見つけ出し、その作業の結果を保存する方法を見つけ出し、後で作業メソッドが呼び出されたときに中断したところから再開することです。すべてのプレーヤーの行儀が良ければ、行き詰まることなくスレッドを共有できます。

スレッド化されたパスをたどる場合、誰がどのメモリにいつアクセスできるかという問題は、もう少し複雑になります。

于 2009-12-26T07:44:53.093 に答える