2016-08-16 3 views
0

아래는 테스트 한 클래스의 수정 된 예제 클래스입니다.이 클래스가 스레드 안전 클래스인지 여부를 알고 싶습니다.Java에서 인스턴스 변수 및 스레드 안전

다른 게시물과 블로그에서 인스턴스 변수가 반드시 스레드로부터 안전하다고 대답 한 곳을 볼 수 있습니다. (대부분의 프리미티브 유형으로 표시되는 예제)

메서드 외부에서 OutputResponse 객체를 만들고 soapui에서로드 테스트를 수행하면 실패했지만 메서드 내에서 객체를 만들 때 항상로드 테스트가 성공했습니다.

@Service 
public class ExampleProvider { 

    private OutputResponse outputResponse; 

     @Post 
     @Path("/test") 
     @Consumes("application/json") 
    @Produces("application/json") 
     public OutputResponseEntity execute (InputRequest inputRequest) { 

     outputResponse = new OutputResponse(); 
      outputResponse.setSomeValue("this is test"); 
      populateOutputResponse(); 
     } 

     private OutoutResponseEntity<OutputResponse> populateOutputResponse() { 
      if(null != inputRequest) { 
       outputResponse.setSomeOtherValue(inputRequest.getName()); 
      } 
      return new OutputResponseEntity(outputResponse,httpstatus.OK); 
     } 
} 
+0

'@ Service'와 나머지 주석에 어떤 프레임 워크를 사용하고 있습니까? – markspace

+1

아니요, 스레드로부터 안전하지 않습니다. 변경할 수있는 개인 공유 데이터가 있습니다. 그것이 "안전하지 않다"는 정의입니다. 개인 데이터 멤버를 제거하고 메서드에 로컬 인 OutputResponse를 만듭니다. 스레드로부터 안전합니다. – duffymo

+0

@duffymo 메소드 내에서 로컬로 OutputResponse 변수를 작성하는 것은 스레드 안전하고 인스턴스 변수 "스레드 안전하지 않음"으로 유지하는 것을 기대했지만로드 테스트는 항상 두 경우 모두 성공합니다. 두 스레드, 초기 스레드 수는 20으로 시도했습니다. soapui에서 2로 종료 스레드 카운트 .. – jagan

답변

0

귀하의 게시 된 코드는 문법적으로 매우 잘 될 것 같지 않습니다 - 당신은 같은 것을 찾으 셨나요?

public OutputResponseEntity execute (InputRequest inputRequest) { 
    outputResponse = new OutputResponse(); 
    outputResponse.setSomeValue("this is test"); 
    return populateOutputResponse(inputRequest); 
} 

가 당신이 무엇을 의미하는 것이 가정을, 다음은을 사용하는 다중 스레드 것 같다 ExampleProvider의 동일한 인스턴스 그러면 outputResponse을 으로 로컬화한 다음 (이유는 아마 populateOutputResponse에도 전달할 것입니다) 테스트를 수정합니다.

ExampleProvider의 동일한 인스턴스를 여러 스레드에서 사용하는 경우 이제 코드가 outputResponse이기 때문에 해당 스레드간에 공유되며 경쟁 조건을 방지하기 위해 동기화가 수행되지 않습니다. 그래서,이 같은 일이 일어날 수 :

  • 스레드 outputResponse
  • JVM 컨텍스트의 공유 인스턴스에 setSomeOtherValue(...) 2 스레드로 전환하고 outputResponse의 동일한 인스턴스에 setSomeValue(...)을 완료 한 완료. outputResponse에는 이제 스레드 1과 2의 상태가 모두 포함됩니다.
  • JVM 컨텍스트는 다시 스레드 1로 전환 한 다음이 혼합 상태 객체를 기반으로 OutputResponseEntity을 생성합니다. 당신이 execute 방법 로컬 outputResponse을 그냥 주위를 통과하면 당신이 스레드 당 해당 개체의 별도의 인스턴스를해야합니다 있도록

는, 효과적으로, 스레드 로컬 메모리가된다. 이것은 아마도 당신이 원하는 것입니다. 스레드간에 정보를 공유 할 필요가 없다면 로컬 var로 만드십시오. 스레드 간 세트/가져 오기 (이 간단한 예제에서는 그렇지 않은 것 같습니다)를 조정해야하는 경우 일종의 동기화를 수행하거나 프로그램 흐름을보다 잘 디자인해야합니다 (너의 요구).

0

이 클래스는 의도적으로 스레드로부터 안전하지 않습니다. 그러나 이것은 일부 프레임 워크에서 구성 요소로 사용됩니다. 이 프레임 워크는 스레드간에 ExampleProvider 인스턴스가 공유되지 않도록 보장합니다. 그렇다면 클래스의 스레드 안전성이 중요하지 않으며 테스트 결과에 영향을주지 않습니다.

+0

스프링 프레임 워크가 사용되었고 내 이해에 따라 기본적으로 싱글 톤으로 생성되므로 ExampleProvider는 스레드간에 공유됩니다. – jagan