1

私はテキストベースのゲーム、MUDを開発しています。プログラムの基本機能の準備ができました。次に、一度に複数のクライアントに接続できるようにしたいと思います。私はそれを達成するためにスレッドを使用する予定です。

私のゲームでは、各プレイヤーの現在の位置や体力ポイントなどの情報を保存する必要があります。私はそれをデータベースに保持することができましたが、それは非常に速く、時には毎秒変化するので、データベースの使用は非効率的です(私は正しいですか?)。

私の質問は、スレッドは「セッション」として動作できるか、つまり、各ユーザーに固有のデータを保持できるかということです。

はいの場合、それがどのように機能するかを理解するのに役立つリソースを教えていただけますか?

いいえの場合、あなたは何を提案しますか?データベースは良いオプションですか、それとも他の何かをお勧めしますか?

乾杯、エレイスト

4

5 に答える 5

5

はい、できますが、これは驚くほど愚かな方法です。1つには、「クライアントごとに1つのスレッド」モデルに永続的にロックされます。もう1つは、ユーザー間の対話を実装することを困難にする(おそらく不可能にすることさえある)ことです。これは、MUDにあると確信しています。

代わりに、各ユーザーのデータとともに、ユーザーを格納するある種のコレクションを用意してください。永続データをデータベースに保存しますが、変更のたびに一時データを更新する必要はありません。

これを処理する1つの方法は、各ユーザーに「変更された」ブール値を設定することです。ユーザーに重大な変更を加えたら、すぐにデータベースに書き込みます。ただし、それが日常的な重要ではない変更である場合は、「変更された」フラグを設定するだけです。次に、スレッドをときどき実行して、変更されたユーザーをデータベースに書き込みます(そして、「変更された」フラグをクリアします)。

もちろん、適切な同期を使用してください。

于 2012-01-25T20:27:33.467 に答える
4

接続/ユーザーセッションごとのスレッドはスケーリングされません。アクティブにできるスレッドの数はNのみです。ここで、Nは、マシンに搭載されている物理コア/プロセッサーの数と同じです。また、一度に作成できるスレッドの数については、マシンのメモリ量によって制限されます。一部のオペレーティングシステムでは、任意の制限も設定されています

複数のクライアントを処理するスレッドには、魔法のようなものは何もありません。それらはあなたのコードをより複雑にし、決定論的ではなく、したがってあなたが論理エラーを探し始めたときに実際に何が起こっているのかを推論するのを難しくします。

接続/ユーザーセッションごとのスレッドはアンチパターンになります!

スレッドは、並行キューから物事を引き出してデータを処理するステートレスワーカーである必要があります。

キャッシング用の並行マップを調べて(または適切なキャッシングソリューションを使用して)、それらを処理してから別のことを行います。java.util.concurrent何かを正しく実装するために必要なすべてのプリミティブクラスを参照してください。

于 2012-01-25T20:27:22.967 に答える
1

ThreadLocalはあなたの友達です!:)

http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

ThreadLocalは、スレッド自体にストレージを提供します。したがって、2つの異なるスレッドからのまったく同じ呼び出しは、異なるデータを返す/保存します。

最大の危険は、スレッド間にリークがあることです。別のユーザーが他の誰かが使用したスレッドを使用した場合、データをリセット/クリアすることを絶対に確認する必要があります。

于 2012-01-25T20:21:34.627 に答える
1

スレッドとスレッドセーフについて心配する代わりに、HSQLDBのようなインメモリSQLデータベースを使用してセッション情報を格納します。他の利点の中でも、MUDが次のAngry Birdsであることが判明した場合は、より簡単にスケールアップできます。

于 2012-01-25T20:45:36.387 に答える
0

間違いなく、スレッドをセッションとして使用できます。しかし、それは少し外れています。

スレッドの主なポイントは、同時非同期実行の機能です。ほとんどの場合、MUDクライアントから受信したイベントが、制御されていない並列の順序で発生することは望ましくありません。

世界の一貫性を確保するために、インメモリデータベースを使用してゲームの世界を保存します。更新をシリアル化するか、少なくともいくつかの更新をシリアル化します。2人のプレイヤーがHP100でモンスターを並行して攻撃することを想像してください。それぞれが100のダメージを与えます。アップデートをシリアル化しないと、両方のプレイヤーに100のダメージを与えることになりかねません。2人のプレイヤーが同時にモンスターから戦利品を奪うことを想像してみてください。適切なシリアル化がないと、それぞれが戦利品の独自のコピーになってしまう可能性があります。

一方、スレッドはクライアントとの非同期通信に適しています。他の何か(Webサーバーなど)がすでにそれを行っていない限り、そのためにスレッドを使用してください。

于 2012-01-25T20:37:02.720 に答える