1

我正在开发一个网络浏览器游戏,我想问一下线程安全。假设我们有一个域类(数据库实体)用户和 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”的所有方法都是只读的(用户永远不会更改建筑物属性),但是不同的用户将传递给这些方法不同的“MyBuilding”参数。只有拥有这些建筑规范的类才是 Spring 组件。

4

2 回答 2

4

如果一个程序不包含数据竞争,它就是线程安全的。如果一个内存位置被多个线程以访问顺序很重要的方式访问(例如,一个线程写入一个字段,另一个线程读取它),则会发生数据竞争。

换句话说,线程安全是关于协调多个线程对可变状态的访问。因此,如果您仅在初始化期间更改对象的状态,并且在对象可用于其他线程之前完成初始化,则该对象基本上是线程安全的。它的声音就像BuildingSpecification是这样一个物体。

方法参数,用于特定线程对方法的特定调用,仅由该线程访问,因此始终是线程安全的(当然,如果方法参数引用一个对象,则该对象可能被另一个线程访问,即使方法参数不是)。从技术上讲,方法参数存储在线程的堆栈上,而不是所有线程共享的堆上。

于 2013-03-02T12:16:41.467 回答
0

从技术上讲,getHealthPointByBuildingLevel它不是线程安全的。尽管 Spring 初始化在启动时发生在单个线程中,但您仍然可能在另一个线程中看到未初始化的值。不过,这不太可能。

由于您没有更改这些规范类,因此最简单的方法是使它们不可变:

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

// constructor which initializes all fields
}
于 2013-03-02T10:59:41.917 回答