의 내가 가진 다음을 가정 해 봅시다 (그래서 자바 1.4에는 제네릭을 제한하지 맡기) : 웹 애플리케이션 서버와 같은 부하가 높은 멀티 스레드 환경에서정적 캐시를로드하는 가장 좋은 패턴 또는 메서드는 무엇입니까?
public class CacheManager {
static HashMap states;
static boolean statesLoaded;
public static String getState(String abbrev) {
if(!statesLoaded) {
loadStates();
}
return (String) states.get(abbrev);
}
private static void loadStates() {
//JDBC stuff to load the data
statesLoaded = true;
}
}
이 이론적으로 문제가있을 수 있습니다> 1 개 스레드 동시에 캐시를 가져오고로드하려고 시도합니다. (캐시를 초기화하기 위해 웹 응용 프로그램에 시작 코드가 없다고 가정하십시오)
간단히 Collections.synchronizedMap을 사용하여이를 수정하면됩니까? 많은 스레드가 스레드에 액세스하는 경우 get()을 수행 할 때 반환 된 synchronizedMap에 성능 문제가 있습니까?
아니면 동기화되지 않은 HashMap을 가지고 대신로드 메소드 또는 부울 변수를 동기화하는 것이 더 좋을까요? 나는 그 중 하나를 동기화하면 클래스를 잠글 수 있다고 생각합니다.
예를 들어,로드 메소드가 동기화 된 경우, 2 개의 스레드가 동시에 getStates() 메소드를 입력하면 둘 다 statesLoaded가 false임을 알 수 있습니다. 첫 번째 메소드에서 메소드를 잠그고 캐시를로드하고 statesLoaded를 true로 설정합니다. 불행히도, 두 번째 스레드는 statesLoaded가 false라고 이미 평가하고 잠금이 해제되면 load 메소드로 진행합니다. 캐시를 다시로드하지 않습니까?
if(!statesLoaded) {
loadStates();
}
이유 : 당신은이 검사를 동기화해야합니다
그럼 잠금 개체는 무엇이되어야합니까? 국가 HashMap? 병목 현상을 일으키지 않을까요? 이 CacheManager 내부에 여러 개의 HashMap이 있으면 어떻게 될까요? 부하 체크의 락 오브젝트로서 특정의 HashMap를 사용하면 (자), static 클래스 전체를 잠글 수 없습니까. – user26270
그래서 당신은 포함 된 객체를 자물쇠로 잠그거나 간단한 객체를 제공 할 수 있습니다 : Object lock = new Object(); 이 방법에 대한 자물쇠가 될 것입니다. –
get()을 잠그지 않는 것을 잊지 마세요. –