1

私はウェブブラウザゲームを開発していますが、スレッドセーフについて質問したいと思います。ドメインクラス(データベースエンティティ)UserとMyBuildingがあるとしましょう:

class User
{
public String name;
List<Building> myBuildings = new ArrayList<Building>();
}

class MyBuilding
{
public int buildingId;
public int level;
}

ここで、ユーザーはたとえば建物のヘルスポイントを取得したいと考えています。これらの建物の仕様に関する情報を格納する別のクラスがあります。これはデータベースに保存する必要はありません。これらは「建物の仕様」クラスであり、Webアプリケーションの開始時にxmlファイルから初期化されます。例えば:

@Component
class BuildingSpecificationHolder
{
public List<BuildingSpecification> buildings = new ArrayList<BuildingSpecification>();
}

//以下のクラスはSpringコンポーネントではなく、単純なクラスです

class BuildingSpecification
{
public int getHealthPointByBuildingLevel(MyBuilding usersBuilding)
{
return usersBuilding.getLevel() * 10;
}

そして今、私の質問は次のとおりです。'public int getHealthPointByBuildingLevel(MyBuilding usersBuilding)'スレッドは安全ですか?同時に異なるユーザーがhpを構築したい場合、それらはすべて、NON-springオブジェクトにある上記のメソッドにアクセスします。'BuildingSpecification'のすべてのメソッドは読み取り専用です(ユーザーがBuildingプロパティを変更することはありません)が、異なるユーザーがそれらのメソッドに異なる'MyBuilding'パラメーターを渡すことに注意してください。これらのBuildings仕様を保持するクラスのみがSpringコンポーネントです。

4

2 に答える 2

4

プログラムにデータ競合が含まれていない場合、そのプログラムはスレッドセーフです。データ競合は、アクセスの順序が問題となるような方法で複数のスレッドがメモリ位置にアクセスする場合に発生します (たとえば、あるスレッドがフィールドに書き込み、別のスレッドがそれを読み取ります)。

別の言い方をすれば、スレッド セーフとは、複数のスレッドによる変更可能な状態へのアクセスを調整することです。したがって、初期化中にオブジェクトの状態のみを変更し、オブジェクトが他のスレッドで使用可能になる前に初期化が完了した場合、そのオブジェクトは単純にスレッド セーフです。その音のようなBuildingSpecificationオブジェクトです。

特定のスレッドによるメソッドの特定の呼び出しのためのメソッド パラメーターは、そのスレッドによってのみアクセスされるため、常にスレッド セーフです (もちろん、メソッド パラメーターがオブジェクトを参照する場合、そのオブジェクトは別のスレッドによってアクセスされる可能性があります)。 、メソッド パラメーターがそうでない場合でも)。技術的に言えば、メソッド パラメーターは、すべてのスレッドで共有されるヒープではなく、スレッドのスタックに格納されます。

于 2013-03-02T12:16:41.467 に答える