0

特定のスレッドが提供されたクラスのインスタンスとして実行しているセルオートマタンを実行しています。新しい機能、つまりシミュレーションの進行中にマウス入力を介してライブ セルを追加するには、メイン スレッドからシミュレーションを実行しているクラスのインスタンスにアクセスして、Draw クラスが使用する 2D コンテナーという名前の ArrayList> "world" を変更する必要があります。参考に塗装します。

しかし、ArrayList はスレッドセーフではなく、エラーが発生します。この時点で、セルの「世界」は 50x50 しかありませんが、そのサイズを 10000^2 またはそれ以上に拡張したいと考えています。(私はその大きさで quadTrees を使用します)

したがって、私の質問は、スレッドセーフであり、すべてのシステム リソースを大量に使用せず、quadTree の概念と「互換性がある」、どのような種類のコンテナーを使用する必要があるかということです。

私はマルチスレッドについてよく知りません。このような重いスレッドを気にする場合、アイデアを破棄する必要がありますか?それとも、ユーザーの入力を評価する間、スレッドを一時停止できますか?(実際に試してみました。スレッドをスリープ状態になり、その間にインスタンスにアクセスしようとしましたが、成功しませんでした。)

いくつかのスレッドセーフなコンテナーを確認しましたが、それらのパフォーマンスは、それらを反復処理するか、それらのプロパティを編集するかなどによって異なります。考慮すべきことが多すぎます。どなたかがどの方向を選択すればよいか教えていただければ幸いです、アンドリュー。

4

3 に答える 3

1

ダブル バッファリングに似た概念を使用できます。したがって、2 つの異なる平面があり、それらをAおよびBと呼びましょう。すべての平面は、細胞の「世界」全体を表しています。UI スレッドは、画面上に平面を描画できます。

最初の繰り返しでは、プレーンBはプレーンAから読み取ることによって更新されます。プレーンAは読み取りのみで書き込みは行われず、プレーンBは書き込みのみで読み取りは行われないため、これはロックなしでマルチスレッドで実行できます。プレーンをセクションに分割し、すべてのセクションを別のスレッドに割り当てるだけです。これは、 fork/join フレームワークを使用して動的に行うことができます。

最初の反復が完了したら、プレーンBを UI スレッドに渡します。それまでの間、次の反復を開始できます。これは、平面Bから平面Aに読み取るようになりました。これも並行して行うことができます。

一般に、次の規則に従います。

  • すべての反復で、1 つのプレーンは読み取り専用で、もう 1 つのプレーンは書き込み専用です。
  • UI スレッドは、再描画のために常に読み取り専用プレーンを参照します。
  • セル更新スレッドには、読み取り用と書き込み用の重複しない個別のセクションがあります。
  • 唯一の同期は、平面が切り替わるすべての反復の最後にあります。

ForkJoinPoolJava には、ExchangerCyclicBarrierなどの優れた同時実行ツールがあります。

UI スレッドが UI 全体を常に更新する必要がないように、書き込み専用プレーンは 1 つまたは複数のダーティ領域を維持できます。ただし、注意してください。ダーティ リージョンは、すべてのスレッドが同期する必要があるため、ボトルネックになる可能性があります。

于 2014-08-14T14:12:59.120 に答える
0

スレッドが 2 つしかなく、オートマトン スレッドを記述してクリティカル セクションへのアクセスを定期的に放棄できる場合は、再入可能ロックを検討することをお勧めします:
http://docs.oracle.com/javase/7/docs /api/java/util/concurrent/locks/ReentrantLock.html

そのセマンティクスは簡単で、関与するスレッドの数が少ない場合に最適に機能します。

于 2014-08-14T12:45:34.800 に答える