我有一个无状态 Java 应用程序部署到一个 tomcat Web 服务器。由于数据的性质,在任何给定时间,所有 http 线程都必须处理不同的密钥(换句话说:所有线程必须处理不同的密钥)。
因此,我编写了一个模块,如果请求的键是当前正在进行的(在此之前的 http 帖子),则将 http 帖子排队。只有在上一个具有相同密钥的 http 帖子完成其处理后,我才会继续处理当前的 http 帖子。
我用 concurrenthashmap 写了一个简单的 while 循环来测试是否有任何先前的请求在进行中。性能低于标准,并且存在意外行为。这是代码片段:
//This part of code is place inside the servlet
private static ConcurrentHashMap<String, String> transQueue = new ConcurrentHashMap<String, String>();
private void inQueuePoll(String queueKey) {
while(transQueue.containsKey(queueKey)){
synchronized(this){
try{
Thread.sleep(50); // i know this is bad, any idea to improve this?
logger.trace("Wait for Que Key: "+queueKey + " );
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
transQueue.put(queueKey, "");
}
在每个 http 帖子的最后,在 finally 块中,我输入: transQueue.remove(queueKey) 以确保我已将其从并发哈希图中删除。然而,在我最糟糕的噩梦中,从服务器日志中,我注意到在我删除 queueKey 之前,另一个 http post 线程设法摆脱了上面的 while 循环并继续处理。
我在上面的代码中做错了什么来“排队”http线程吗?
也非常感谢任何关于我如何能更好地做到这一点的想法。