限制JAX-WS CXF Web服务请求方法调用为每个客户端IP只有一个请求

3

我有一个基于CXF的Web服务,其中有一个单向方法:Service.report()

当正在处理来自客户端的report()请求时,我希望能让同一客户端IP的另一个进入的report()请求等到第一个请求被处理完毕。从客户端的角度来看,report()是一个原子操作,对report()的连续调用应该按顺序进行处理。

我最好如何实现这种锁定机制?是否需要实现每个客户端队列,还是有简单的方法可以实现此目的?


这个能跟**synchronized report()**一起使用吗? - pd40
1个回答

1

你不需要一个完整的队列来实现这个。一个简单的对象同步应该就可以了。

static ConcurrentMap syncMap = new ConcurrentHashMap();

public void report()
{
   String clientIp =  ...
   syncMap.putIfAbsent(clientIp, new Object()); // just new Object is good enough to sync on
   synchronized(syncMap.get(clientIp))
   {
      //do synchronized stuff.
   }
}

虽然这是一个完美的解决方案,但我建议使用更加强大的解决方案。使用这种类型的同步会使线程处于等待状态,直到有机会工作。如果您使用某种执行器模式,那么在我看来就不需要这个__大而昂贵的__同步了。 - Gergely Szilagyi
除非您使用servlet 3.0,否则您需要在任何情况下保持HTTP请求的工作线程被阻塞。 - GeertPt
感谢 @greyfairer!在处理完请求后,我如何最好地清除映射中的客户端IP?这会引起问题吗?synchronized(syncMap.get(clientIp)) { //进行同步操作。 syncMap.remove(clientIp); } - amo
一个remove操作总是原子性的,因此您可以安全地执行该操作。但我不认为有必要这样做。如果您退出同步块,则同步对象将被解锁并可以在下一次调用中重复使用,因此您可以将其保留在映射中。除非您的内存真的很有限。 - GeertPt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接