이 문제를 해결하는 주류 방법은 특정 타이머 스레드를 사용하여 지정된 간격으로 캐시를 새로 고치는 것입니다. 그러나 새 스레드를 만들 필요가 없기 때문에 생각할 수있는 구현은 의사 타이밍에 의한 캐시 새로 고침입니다. 기본적으로 캐시 접근자를 넣고 (put 및 get 메서드) 클라이언트가이 메서드를 사용할 때마다 캐시를 넣거나 수행하기 전에 캐시를 새로 고쳐야하는지 확인합니다. 이 거친 생각입니다 :
class YourCache {
// holds the last time the cache has been refreshed in millis
private volatile long lastRefreshDate;
// indicates that cache is currently refreshing entries
private volatile boolean cacheCurrentlyRefreshing;
private Map cache = // Your concurrent map cache...
public void put(Object key, Object element) {
if (cacheNeedsRefresh()) {
refresh();
}
map.put(key, element);
}
public Object get(Object key) {
if (cacheNeedsRefresh()) {
refresh();
}
return map.get(key);
}
private boolean cacheNeedsRefresh() {
// make sure that cache is not currently being refreshed by some
// other thread.
if (cacheCurrentlyRefreshing) {
return false;
}
return (now - lastRefreshDate) >= REFRESH_INTERVAL;
}
private void refresh() {
// make sure the cache did not start refreshing between cacheNeedsRefresh()
// and refresh() by some other thread.
if (cacheCurrentlyRefreshing) {
return;
}
// signal to other threads that cache is currently being refreshed.
cacheCurrentlyRefreshing = true;
try {
// refresh your cache contents here
} finally {
// set the lastRefreshDate and signal that cache has finished
// refreshing to other threads.
lastRefreshDate = System.currentTimeMillis();
cahceCurrentlyRefreshing = false;
}
}
}
는 개인적으로 난과 같이 그 일을 생각하지,하지만 당신이 원하는하지 않거나 타이머 스레드를 작성할 수없는 경우 다음이 당신을위한 옵션이 될 수 있습니다.
이 구현은 잠금을 피할 수 있지만 경쟁 이벤트로 인해 새로 고침을 반복하는 경향이 있습니다. 이것이 당신의 요구 사항에 대해 괜찮 으면 아무 문제가 없어야합니다. 그러나보다 엄격한 요구 사항이있는 경우 스레드를 올바르게 동기화하고 경쟁 이벤트를 피하기 위해 잠금을 설정해야합니다.
EHCache와 같은 라이브러리를 사용하지 않는 이유는 무엇입니까? – beny23
EHCache를 사용하여 동일한 @ benny23을 제안합니다. XML 파일에서 새로 고침 시간을 구성하는 것만 큼 간단합니다. 프로그래밍 방식으로하지 않을 경우 – jmventar
이것은 많은 다른 응용 프로그램에 포함 된 라이브러리에서 사용되며 일부는 라이브러리에 사용됩니다. 아주 나쁜 모양. 라이브러리에는 이미 많은 종속성이 있습니다. 히스토리는 도입 된 각 의존성이 애플리케이션의 유지 보수를 더욱 어렵게한다는 것을 입증했습니다. 버전 충돌 등을 소개합니다. 이것은 내가 의존성을 없애고 새로운 것을 도입하지 말아야한다는 것을 의미합니다. – hyperman