4

次のゲームサーバーを作成しましたが、グループ機能を提供したいと思います。グループを使用すると、画面上で「近くにいる」プレーヤーをグループ化できます。高速アクションゲームでは、プレーヤーが常にゾーンに出入りするため、このグループは急速に変化します。

各プレイヤーはグループ内の他のプレイヤーからのイベントを聞く必要があるため、プレイヤーはグループにサブスクライブします。これは私の質問に私をもたらします。このシナリオでグループのイベントリスナーの変化するセットを保持するために使用できる適切なデータ構造またはJavaコレクションクラスは何ですか?私の意見では、グループのリスナーの数が20を超えることはめったになく、ほとんどのシナリオではそれよりも少ないはずです。これはマルチスレッド環境です。

私が使用することを計画しているのはCopyOnWriteArrayListです。しかし、(サブスクリプションの変更により)適度な量の更新があるので、このクラスは適切ですか?他にどのクラスを使用するとよいでしょうか?配列などを使用したカスタム実装がある場合は、共有してください。

4

3 に答える 3

2

1秒あたり数百万の変更がない限り(シナリオではありそうもないようです)、CopyOnWriteArrayList必要なものには十分なはずです。もし私があなたなら、それを使います。

パフォーマンスの問題に気づき、アプリケーションのプロファイルを作成し、それがボトルネックであると特定したCopyOnWriteArrayList場合は、より適切な構造を見つけることができます。しかし、そうなるとは思えません。

于 2012-05-09T09:24:29.853 に答える
1

私が集めたものから、あなたはとの間の選択がCopyOnWriteArrayListありConcurrentHashMapます:

CopyOnWriteArrayList:

  1. 追加/削除操作の計算コストは​​、リストのサイズに比例します。1回の反復中に複数回発生する可能性があります(グループ通知)。
  2. 一定の読み取り時間を持つより単純なデータ構造。

ConcurrentHashMap:

  1. 追加/削除操作は定数時間操作です。サブスクライバーの追加または削除は、すでに進行中の反復に影響を与えず、ブロッキングは最小限に抑えられます。
  2. わずかに長い読み取り時間を必要とするより大きなデータ構造。

カスタムソリューションの作成は、効率に関しては可能ですが、スレッドセーフに関してはおそらくそれほど安全ではありません。私は傾いてConcurrentHashMapいますが、勝者はおそらくあなたのゲームがどうなるかに大きく依存します。

于 2012-05-09T06:30:44.930 に答える
1

プレイヤーは整数IDを持っていますか?もしそうなら、私はあなたにとって意味があるかもしれない軽量で不変の配列ベースのセットクラスを持っています:

これは、ゲームエンジンの同様の状況のた​​めに書かれました。

ただし、考慮すべき別のアプローチもあります。近隣に基づいてグループを自動的に更新する場合は、グループをまったく追跡しないことを検討することをお勧めします。代わりに、イベントが発生するたびに近くのプレーヤーをすばやく検索し、イベントを近くのプレーヤーに直接送信できる空間データ構造の使用を検討してください。

通常、最小分割サイズがグループの最大範囲と等しくなるように設定された2Dまたは3Dグリッドまたは八分木を使用できます。次に、近隣検索では、9(2Dの場合)または27(3Dの場合)の場所をチェックするだけで、近くのすべてのプレーヤーを見つけることができます。必要なときにいつでもこの検索を実行すると、グループとリスナーのリストを常に維持するオーバーヘッドよりも高速で簡単になると思います。

于 2012-05-09T09:36:10.000 に答える