문제
내 웹 앱에 클래스 "foo"라는 클래스가 있다고 가정 해 봅시다. 스프링을 사용하여 콩을 만들 때 호출되는 초기 () 메소드가 있습니다. 그런 다음 initialise () 메소드는 외부 서비스를로드하여 필드에 할당하려고합니다. 서비스에 연락 할 수없는 경우 필드는 NULL로 설정됩니다.
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
}
누군가가 "foo"클래스에서 메소드를 get ()를 호출하면 초기 () 메소드에서 시작된 경우 서비스가 호출됩니다. 서비스 필드가 NULL 인 경우 외부 서비스를 시도하고로드하고 싶습니다.
public String get() {
if (service == null) {
// try and load the service again
}
// perform operation on the service is service is not null
}
이런 일을한다면 동기화 문제가있을 수 있습니까?
해결책
툴킷대답이 맞습니다. 문제를 해결하려면 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
}
다른 팁
예, 동기화 문제가 있습니다.
단일 서블릿이 있다고 가정하자 :
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 정의는 다음과 같습니다.
<bean id="myBean" class="com.foo.MyBean" init-method="initialise" />
문제는 여러 요청 스레드에서 서블릿 인스턴스를 사용한다는 것입니다. 따라서 Service == NULL에 의해 보호 된 코드 블록은 여러 스레드에 의해 입력 될 수 있습니다.
최상의 수정 (이중 체크 고정 등을 피하기 등)은 다음과 같습니다.
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
}
}
이것이 말이되기를 바랍니다. 그렇지 않은 경우 의견을 남겨주세요.
제휴하지 않습니다 StackOverflow