캐시 공급자로 사용되는 클래스를 만들었습니다. Map, timestamped map 엔트리를 사용하며 매번 정리 작업을 수행하는 Thread를 생성합니다. 이 클래스는 웹 응용 프로그램에서 사용됩니다. 이 웹 응용 프로그램에는 POST에 30 초가 걸리는 문제가있었습니다. 이 캐시 클래스로 문제를 추적하여 문제를 해결했습니다.이 스레드 코드의 오류는 어디에 있습니까?
나는이 수업에서 오류를 찾기 위해 최선을 다했으나하지 못했습니다. 제발 도와주세요. 사용자 클래스는 사용자를 설명하는 일종의 POJO라고 가정합니다.
public class UserStore implements Thread.UncaughtExceptionHandler {
private static volatile UserStore instance;
private static Thread cleanUpThread;
private static Map<String, TimeStampedToken<User>> tokenMap = new HashMap<String, TimeStampedToken<User>>();
public static UserStore getInstance() {
if (instance == null) {
synchronized(UserStore.class) {
if (instance == null) {
instance = new UserStore();
cleanUpThread = new Thread(new CleanUpWorker());
cleanUpThread.setUncaughtExceptionHandler(instance);
cleanUpThread.start();
}
}
}
return instance;
}
public void uncaughtException(Thread thread, Throwable throwable) {
if (throwable instanceof ThreadDeath) {
cleanUpThread = new Thread(new CleanUpWorker());
cleanUpThread.setUncaughtExceptionHandler(this);
cleanUpThread.start();
throw (ThreadDeath)throwable;
}
}
private static class CleanUpWorker implements Runnable {
private static final long CLEANUP_CYCLE_MS = 300000;
private static final long OBJECT_LIVE_TIME = 299900;
public void run() {
long sleepRemaining;
long sleepStart = System.currentTimeMillis();
sleepRemaining = CLEANUP_CYCLE_MS;
while (true) {
try {
sleepStart = System.currentTimeMillis();
Thread.sleep(sleepRemaining);
cleanUp();
sleepRemaining = CLEANUP_CYCLE_MS;
} catch (InterruptedException e) {
sleepRemaining = System.currentTimeMillis() - sleepStart;
}
}
}
private void cleanUp() {
Long currentTime = System.currentTimeMillis();
synchronized(tokenMap) {
for (String user : tokenMap.keySet()) {
TimeStampedToken<User> tok = tokenMap.get(user);
if (tok.accessed + OBJECT_LIVE_TIME < currentTime) {
tokenMap.remove(user);
}
}
}
}
}
public void addToken(User tok) {
synchronized(tokenMap) {
tokenMap.put(tok.getUserId(), new TimeStampedToken<User>(tok));
}
}
public User getToken(String userId) {
synchronized(tokenMap) {
TimeStampedToken<User> user = tokenMap.get(userId);
if (user != null) {
user.accessed = System.currentTimeMillis();
return user.payload;
} else {
return null;
}
}
}
private static class TimeStampedToken<E> {
public TimeStampedToken(E payload) {
this.payload = payload;
}
public long accessed = System.currentTimeMillis();
public E payload;
}
}
캐시 클래스의 기능과 정확히 무슨 문제입니까? 그것은 (기능) 잘못 작동합니까? 아니면 (POST가 너무 오래 걸리는) 원하는 속도보다 느리게 작동합니까? 그렇다면 어떤 메소드 호출에 너무 많은 시간이 소요됩니까? – ArjunShankar
스레드를 구체적으로 중지하라는 메시지가 표시되는 경우에만 스레드를 다시 시작하는 이유는 무엇입니까? –
만료 날짜가있는 캐시를 구현하려는 것 같습니다. 이것을 구현하는 훨씬 간단한 방법이 있거나, 이미 이것을하는 라이브러리를 사용할 수 있습니다. –