英文:
how to create thread on Map<k,v> that work all the time and remove key from the map?
问题
以下是您要翻译的内容:
我正在编写优惠券系统的REST API,
并且我正在尝试创建一个在线程,该线程在服务器运行时始终工作。
该线程需要在客户端在10秒内未通过控制器类使用服务器时(通过客户端会话)移除令牌+客户端会话。
线程类:
public class ClientSessionCleaner implements Runnable {
private boolean run = true;
private Map<String, ClientSession> tokensMap;
public ClientSessionCleaner() {
/*空*/
}
@Autowired
public ClientSessionCleaner(@Qualifier("tokens") Map<String, ClientSession> tokensMap) {
this.tokensMap = tokensMap;
}
@Override
public void run() {
HashMap<String, ClientSession> copy = new HashMap<>(tokensMap);
do {
CleanMap(copy);
} while (run);
}
private void CleanMap(HashMap<String, ClientSession> copy) {
copy.forEach((k, v) -> {
if (System.currentTimeMillis() - v.getLastAccessMillis() == 10 * 1_000){
copy.remove(k);
}
});
}
我在主类中启动线程,这样可以吗?
public static void main(String[] args) {
SpringApplication.run(CouponSystemApplication.class, args);
ClientSessionCleaner cleaner = new ClientSessionCleaner();
Thread thread = new Thread(cleaner);
thread.start();
}
当我启动服务器时,我收到以下错误:
Exception in thread "Thread-178" java.lang.NullPointerException
at java.base/java.util.HashMap.putMapEntries(HashMap.java:496)
at java.base/java.util.HashMap.<init>(HashMap.java:485)
at com.Avinadav.couponsystem.rest.login.ClientSessionCleaner.run(ClientSessionCleaner.java:25)
at java.base/java.lang.Thread.run(Thread.java:834)
令牌映射:
@Configuration
public class RestConfiguration {
@Bean(name = "tokens")
public Map<String, ClientSession> tokensMap() {
return new HashMap<>();
}
}
我不知道线程代码是否正确(?),以及我应该如何使线程工作。
我对线程不太熟悉,非常感谢您的帮助!
英文:
I'm writing REST API of coupons system,
and I'm trying to create a thread that works all the time that the server is running.
The thread needs to remove the token+client session if the client doesn't use the server (through the controllers class) passes 10 seconds.
The class of the thread:
public class ClientSessionCleaner implements Runnable {
private boolean run = true;
private Map<String, ClientSession> tokensMap;
public ClientSessionCleaner() {
/*Empty*/
}
@Autowired
public ClientSessionCleaner(@Qualifier("tokens") Map<String, ClientSession> tokensMap) {
this.tokensMap = tokensMap;
}
@Override
public void run() {
HashMap<String, ClientSession> copy = new HashMap<>(tokensMap);
do {
CleanMap(copy);
}while (run);
}
private void CleanMap(HashMap<String, ClientSession> copy) {
copy.forEach((k, v) -> {
if (System.currentTimeMillis() - v.getLastAccessMillis() == 10 * 1_000){
copy.remove(k);
}
});
}
I'm starting the thread in the main class, it is ok?
public static void main(String[] args) {
SpringApplication.run(CouponSystemApplication.class, args);
ClientSessionCleaner cleaner = new ClientSessionCleaner();
Thread thread =new Thread(cleaner);
thread.start();
}
When I'm starting the server I'm getting this:
Exception in thread "Thread-178" java.lang.NullPointerException
at java.base/java.util.HashMap.putMapEntries(HashMap.java:496)
at java.base/java.util.HashMap.<init>(HashMap.java:485)
at com.Avinadav.couponsystem.rest.login.ClientSessionCleaner.run(ClientSessionCleaner.java:25)
at java.base/java.lang.Thread.run(Thread.java:834)
The tokens map:
@Configuration
public class RestConfiguration {
@Bean(name = "tokens")
public Map<String, ClientSession> tokensMap() {
return new HashMap<>();
}
}
I don't know if the thread code is ok (?) and what I should do to make the thread work.
I'm new with threads,
thx for all the help!
答案1
得分: 1
如果我理解正确,看起来您正在尝试实现一种清理过期的 ClientSession
的服务。是这样吗?
如果是这样的话,您的 Runnable
实际上可以是一个 @Component
,其中 @Scheduled
注解将定义一个定期的过程,用于进行清理。
有关调度的更多信息,请查看Spring 中的 @Scheduled 注解。
英文:
If I understand you correctly, it seems like you're trying to implement some kind of a cleanup service for outdated ClientSession
s. Is that right?
If so, your Runnable
can actually be a @Component
in which a @Scheduled
annotation will define a periodic procedure in which the cleaning will take place.
For more info about Scheduling, check out the The @Scheduled Annotation in Spring
答案2
得分: 0
你的用例 可能 适用于流行的缓存库,比如 Caffeine 或 Google Guava,因为它们支持带有 基于时间的过期策略 的映射,而这似乎是你想要实现的目标。
LoadingCache<String, ClientSession> tokensMap = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
对于更复杂的逻辑,可以使用 LoadingCache#expireAfter
。使用这样的库将可以避免你处理复杂的并发问题。
英文:
Your use-case may fit the functionality of a popular caching library like Caffeine or Google Guava, because it has support for maps with time-based eviction and it seems to be me that's what you're trying to accomplish.
LoadingCache<String, ClientSession> tokensMap = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
For more complex logic use LoadingCache#expireAfter
. Using a library like this will prevent you from having to deal with complex concurrency issues.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论