如何在 Map<k,v> 上创建一直工作的线程并从地图中删除键?
how to create thread on Map<k,v> that work all the time and remove key from the map?
我正在编写优惠券系统的 REST API,
我正在尝试创建一个线程,该线程在服务器 运行.
期间一直有效
如果客户端不使用服务器(通过控制器class)超过 10 秒,线程需要删除令牌+客户端会话。
线程的class:
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);
}
});
}
我在主线程启动class,可以吗?
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<>();
}
}
我不知道线程代码是否可以(?)以及我应该怎么做才能使线程工作。
我是线程的新手,
谢谢大家的帮助!
您的 use-case 可能 适合像 Caffeine or Google Guava, because it has support for maps with time-based eviction 这样流行的缓存库的功能,而您似乎就是我想要完成的.
LoadingCache<String, ClientSession> tokensMap = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
对于更复杂的逻辑,请使用 LoadingCache#expireAfter
。使用这样的库将使您不必处理复杂的并发问题。
如果我没有理解错的话,您似乎在尝试为过时的 ClientSession
实施某种清理服务。是吗?
如果是这样,您的 Runnable
实际上可以是一个 @Component
,其中 @Scheduled
注释将定义一个周期性的清洁过程。
有关日程安排的更多信息,请查看 The @Scheduled Annotation in Spring
我正在编写优惠券系统的 REST API, 我正在尝试创建一个线程,该线程在服务器 运行.
期间一直有效如果客户端不使用服务器(通过控制器class)超过 10 秒,线程需要删除令牌+客户端会话。
线程的class:
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);
}
});
}
我在主线程启动class,可以吗?
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<>();
}
}
我不知道线程代码是否可以(?)以及我应该怎么做才能使线程工作。 我是线程的新手, 谢谢大家的帮助!
您的 use-case 可能 适合像 Caffeine or Google Guava, because it has support for maps with time-based eviction 这样流行的缓存库的功能,而您似乎就是我想要完成的.
LoadingCache<String, ClientSession> tokensMap = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
对于更复杂的逻辑,请使用 LoadingCache#expireAfter
。使用这样的库将使您不必处理复杂的并发问题。
如果我没有理解错的话,您似乎在尝试为过时的 ClientSession
实施某种清理服务。是吗?
如果是这样,您的 Runnable
实际上可以是一个 @Component
,其中 @Scheduled
注释将定义一个周期性的清洁过程。
有关日程安排的更多信息,请查看 The @Scheduled Annotation in Spring