2008-10-22 8 views
1

내 웹 응용 프로그램에 "Foo"클래스라는 클래스가 있다고 가정 해 봅니다. Spring을 사용하여 bean을 생성 할 때 호출되는 initialise() 메소드가있다. 그런 다음 initialise() 메서드는 외부 서비스를로드하여 필드에 할당하려고합니다. 서비스에 접속할 수없는 경우 필드는 null로 설정됩니다.Java 웹 응용 프로그램 동기화 질문

private Service service; 

public void initialise() { 
    // load external service 
    // set field to the loaded service if contacted 
    // set to field to null if service could not be contacted 
} 

누군가가 초기화() 메소드에서 시작 된 경우 서비스가 호출되는 클래스 "푸"에서의 메소드 GET()를 호출합니다. 서비스 필드가 null 인 경우 외부 서비스를로드하려고합니다.

public String get() { 
    if (service == null) { 
     // try and load the service again 
    } 
    // perform operation on the service is service is not null 
} 

이와 같은 작업을 수행하면 동기화 문제가 발생할 수 있습니까?

답변

1

툴킷의 답이 맞습니다. 문제를 해결하려면 Foo의 initialise() 메소드를 동기화하도록 선언하십시오. Foo를 다음과 같이 리팩토링 할 수 있습니다.

private Service service; 

public synchronized void initialise() { 
    if (service == null) { 
     // load external service 
     // set field to the loaded service if contacted 
    } 
} 

public String get() { 
    if (service == null) {    
     initialise(); // try and load the service again 
    } 
    // perform operation on the service is service is not null 
} 
+0

고마워요! 리팩토링과 함께 좋은 아이디어;) – digiarnie

+0

그것은 이중 검사 잠금의 한 형태이며, 따라서 : 1. 이것은 Java 5 이상에서만 작동합니다. 2. "서비스"는 휘발성으로 선언되어야합니다. –

+0

참조 : http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html –

0

예, 동기화 문제가 있습니다.

는 하나의 서블릿이 있다고 가정하자 :

public class FooServlet extends HttpServlet { 

    private MyBean myBean; 

    public void init() { 
     myBean = (MyBean) WebApplicationContextUtils. 
      getRequiredWebApplicationContext(getServletContext()).getBean("myBean"); 
    } 

    public void doGet(HttpRequest request, HttpResponse response) { 
     String string = myBean.get(); 
     .... 
    } 

} 

class MyBean { 
    public String get() { 
     if (service == null) { 
      // try and load the service again 
     } 
     // perform operation on the service is service is not null 
    } 
} 

과 같이 당신의 빈 정의가 같습니다

<bean id="myBean" class="com.foo.MyBean" init-method="initialise" /> 

문제는 서블릿 인스턴스가 여러 요청 스레드가 사용된다는 점이다. 이 때문에, 서비스에 의해 감시되는 코드 블록 == null가 복수의 thread에 의해 입력 될 가능성이 있습니다.

가장 좋은 수정 (피 재확인 잠금 등)이다이 말이

class MyBean { 
    public synchronized String get() { 
     if (service == null) { 
      // try and load the service again 
     } 
     // perform operation on the service is service is not null 
    } 
} 

희망. 댓글이 없으면 삭제합니다.

+0

감사합니다. 그러나이 방법을 동기화하여 간단하게 해결할 수 있습니까? 아니면 그 다음에는 더 많은 것이 있습니까? – digiarnie

관련 문제