2009-08-03 4 views
0

Axis2 웹 서비스와의 동시성을 처리하는 올바른 최선의 방법을 알고 싶습니다.자바 동시성 : 웹 서비스 액세스 쓰레드 세이프

예는이 코드를 부여 :

public class MyServiceDelegate 
{ 
    @Resource 
    UserWebService service; // Injected by spring 

    public CustomerDTO getCustomer() 
    { 
     String sessionString = getSessionStringFromCookies(); 
     service.setJSESSIONID(sessionString); 
     CustomerDTO customer = service.getCustomerFromSessionID(); 
    } 
} 

참고 UserWebService 위가 제 3 자 API입니다에 그. 이 서비스는 전화를 걸 때 인증 된 세션으로 JSESSIONID의 쿠키를 전달해야합니다.

이 문장이 threadsafe가 아니라고 가정하면 올바르게 맞습니까? IE., 두 개의 스레드가 주어지면 다음과 같은 현상이 발생할 수 있습니까?

  • ThreadA : service.setJSESSIONID("threadA")
  • ThreadB : service.setJSESSIONID("threadB")
  • ThreadA : 그렇다면 service.getCustomerFromSessionID // service.sesionID == "threadB"

,이 상황을 처리 할 수있는 가장 적절한 방법은 무엇입니까? 서비스 용 리소스 풀을 사용해야합니까? 아니면 서비스를 동기화 된 것으로 선언해야합니까?

public CustomerDTO getCustomer() 
    { 
     synchronized(service) { 
      service.setJSESSIONID(sessionString); 
      CustomerDTO customer = service.getCustomerFromSessionID(); 
     } 
    } 

이 문제를 해결하는 또 다른 방법이 있습니까?

답변

3

각 스레드는 고유 한 Delegate 개체를 가지므로 자체 UserWebService 서비스를 갖습니까?

간단한 경우 대리인이 스택에 만들어지면 스레드는 독립적입니다.

생성 비용이 높은 경우 대리인 개체 풀을 보유하십시오. teh pool에서 하나를 가져가는 것은 comparativley cheap입니다. 하우스 키핑에 매우주의를 기울일 필요가 있지만 효과적으로 데이터베이스 연결로 수행됩니다. 일부 환경에는 이러한 풀링을 관리하기위한 유틸리티 클래스가 있으며 자신의 롤링보다 바람직합니다.

+0

이것은 가능하지만 비용이 많이 드는 것처럼 보입니다. 현재 대리자는 싱글 톤 범위가있는 스프링 빈으로 선언됩니다. 프로토 타입을 사용하도록 변경할 수 있으므로 매번 위임자와 서비스를 인스턴스화 할 수 있지만 오버 헤드가 많이 발생합니다. 더 좋은 방법이 있습니까? –

+0

대체 디자인을 추가 할 경우 편집 됨 – djna

0

UserWebService가 수업 중 하나입니까? 함수가 스레드 안전 당신이 말했듯이

+0

불행히도, 아니요.그리고 서비스는 호출하기 전에 우리가 사용하고있는 인증 된 세션을 식별 할 수 있도록 JSESSION ID를 서비스에 설정해야합니다. –

+0

나는 세션 ID가 델리게이트 객체에 설정된 것으로 추측하고 있는데, 세션 ID가 개념적으로 쿠키에있는 원격 서비스를 호출한다. 어떤 경우에 통화를 마무리하는 것은 여전히 ​​인종의 가능성을 떠나게됩니다. – djna

0

없는 본질적으로, 당신의 UserWebService 상태를 유지해야 함이있을 것입니다 그런 식으로

public CustomerDTO getCustomer() 
{ 
     CustomerDTO customer = service.getCustomerFromSessionID(sessionString); 
} 

그리고하지 : 그렇다면, 나는에 메서드 서명을 변경 거라고 생각 스레드 안전. Java는 한 번에 하나의 스레드가 하나의 함수에만 액세스 할 수 있도록 허용하는 객체 인 모니터를 만드는 간단한 방법을 제공합니다. monitors

에 대한 자세한 정보는 당신이 그랬던 것처럼 당신이 표현의 주위에, 어느 동기화 둘 수는 스레드 안전 만들거나하는 기능 이름 앞에 : 둘 사이의 차이는 당신이 켜 반대하는

public synchronized CustomerDTO getCustomer(){ 
    service.setJSESSIONID(sessionString); 
    CustomerDTO customer = service.getCustomerFromSessionID(); 
} 

입니다 모니터에.

+1

이 시나리오에서 대리자 풀보다 동기화 된 메서드를 선호하는 이유가 있습니까? (또는 그 반대로) –

+2

웹 서비스 호출 기간 동안 동기화하는 것은 나에게 정말로 나쁜 생각처럼 들립니다. Delegate Pool은 제가 갈 방법입니다. – djna