gpt4 book ai didi

java - 这段线程代码的错误在哪里?

转载 作者:行者123 更新时间:2023-12-01 15:37:54 25 4
gpt4 key购买 nike

我创建了一个用作缓存提供程序的类。它使用一个映射、带时间戳的映射条目,并生成一个经常执行清理的线程。此类在 Web 应用程序中使用。此 Web 应用程序存在 POST 需要 30 秒的问题。我跟踪问题到了这个缓存类,排除它就解决了问题。

我已尽力找出该类中的错误,但找不到。请帮我一下。假设 User 类是某种描述用户的 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;
}
}

最佳答案

这是我的处理方法。对于多线程代码,简单性通常是最好的方法,因为它更有效。

(LinkedHashMap的第三个参数true表示此Map上的迭代器遵循访问顺序而不是插入顺序)

public enum UserStore {
;

interface User {
String getUserId();
}

// a LRU cache with a timestamp.
private static final Map<String, TimeStampedToken<User>> tokenMap = new LinkedHashMap<String, TimeStampedToken<User>>(16, 0.7f, true);
private static final long OBJECT_LIVE_TIME = 299900;

public static synchronized void addToken(User tok) {
final long now = System.currentTimeMillis();
// clean up as we go
for (Iterator<Map.Entry<String, TimeStampedToken<User>>> iter = tokenMap.entrySet().iterator(); iter.hasNext(); ) {
final Map.Entry<String, TimeStampedToken<User>> next = iter.next();
if (next.getValue().accessed + OBJECT_LIVE_TIME >= now)
// the map is ordered by access time so there are no more to clean up.
break;
iter.remove();
}
// add a new entry
tokenMap.put(tok.getUserId(), new TimeStampedToken<User>(tok, now));
}

public static synchronized User getToken(String userId) {
final long now = System.currentTimeMillis();
TimeStampedToken<User> user = tokenMap.get(userId);
if (user == null)
return null;

user.accessed = now;
return user.payload;
}

static class TimeStampedToken<E> {
long accessed;
final E payload;

TimeStampedToken(E payload, long now) {
this.payload = payload;
accessed = now;
}
}
}

关于java - 这段线程代码的错误在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8588889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com