2013-03-02 1 views
1

웹 브라우저 게임을 개발 중이며 스레드 안전성에 대해 질문하고 싶습니다.스프링 구성 요소 필드 스레드 안전

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

지금

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

, 사용자가 예를 들면 싶어 : 의 우리가 도메인 클래스 (데이터베이스 엔티티) 사용자 및 MyBuilding 있다고 가정 해 봅시다 건물 건강 지점. 데이터베이스에 저장할 필요가없는 건물 사양에 대한 정보를 저장하는 또 다른 클래스가 있습니다.이 클래스는 건물 사양 클래스이며 XML 파일에서 웹 응용 프로그램을 시작할 때 초기화됩니다. 예를 들면 : // 클래스 아래
@Component 
class BuildingSpecificationHolder 
{ 
public List<BuildingSpecification> buildings = new ArrayList<BuildingSpecification>(); 
} 

는 봄의 구성 요소, 단순한 클래스가 아닙니다

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

그리고 지금 내 질문은 : '공공 INT getHealthPointByBuildingLevel (MyBuilding usersBuilding)' 실인가 안전한가? 동시에 특정 사용자가 건물 hp를 원한다면, 그들은 모두 위에서 설명한 방법 인 에 액세스합니다 (즉, 비 스프링 객체에 있음). 'BuildingSpecification'의 모든 메소드가 읽기 전용 (사용자가 건물 속성을 변경하지 않음)이지만 다른 사용자가 다른 메소드 인 'MyBuilding'매개 변수를 전달한다는 점에 유의하십시오. 해당 건물 사양을 보유하는 클래스 만 스프링 구성 요소입니다.

답변

0

기술적으로 getHealthPointByBuildingLevel은 스레드로부터 안전하지 않습니다. 시작할 때 단일 스레드에서 Spring 초기화가 발생하더라도 다른 스레드에서 아직 초기화되지 않은 값이 표시 될 수 있습니다. 그래도 그럴 가능성은 희박합니다. 이 데이터 경주가없는 경우

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

// constructor which initializes all fields 
} 
+0

흠, 저를 올바르게 이해하지 못했을 것 같아요. 'MyBuilding'은 재생 도중 증가 할 수있는 건물 수준에 대한 필드가 포함되어 있으므로 변경할 수 없습니다. 그래서 나는 그들을 최후의 것으로 만들 수 없다. BuildingSpecificationHolder의 건물 목록이 스레드 안전 인 경우, 해당 메서드에 동시에 액세스하면 요점이 있습니다. – friko

4

프로그램은 스레드 안전 :이 사양 클래스를 변경하지 않는 때문에

는 가장 쉬운 방법은 그들을 변경할 수 있도록하는 것입니다. 데이터 순서는 여러 스레드에서 메모리 위치에 액세스하여 액세스 순서가 중요한 경우 (예 : 한 스레드가 필드를 쓰고 다른 스레드가 읽는 경우) 발생합니다.

다르게 말하면, 스레드 안전성은 여러 스레드에 의한 가변 상태 액세스를 조정하는 것과 관련이 있습니다. 따라서 초기화 중에 객체의 상태 만 변경하고 객체가 다른 스레드에서 사용 가능하게되기 전에 초기화가 완료되면 객체는 거의 스레드로부터 안전합니다. 그 소리는 BuildingSpecification과 같습니다.

특정 스레드에 의한 특정 메서드 호출에 해당하는 메서드 매개 변수는 해당 스레드에서만 액세스되므로 항상 스레드로부터 안전합니다 (물론 메서드 매개 변수가 개체를 참조하면 해당 개체는 메서드 파라미터가없는 경우에서도, 다른 thread에 의해 액세스됩니다). 엄밀히 말하면 메소드 매개 변수는 모든 스레드가 공유하는 힙이 아니라 스레드의 스택에 저장됩니다.