如果在旧的servlet请求完成之前进入新的servlet请求,如何取消它

时间:2013-07-05 15:08:43

标签: tomcat servlets

我有一个JavaScript应用程序,可以允许用户触发多个重叠的只读请求到我的Tomcat服务器,以便以后的请求应该取消并覆盖任何先前的请求。我可以禁用所有客户端控件,直到请求进入,但我宁愿让它们保持启用状态,让用户随时点击,并取消之前的请求。

我想做的是取消除最新请求之外的所有请求,以便我的服务器不会浪费时间完成永远不会看到的请求。我希望服务器中止为该请求运行的线程,以减少服务器资源。

最好的方法是什么?

2 个答案:

答案 0 :(得分:2)

如果只是为了节省服务器CPU时间,客户端取消请求将无济于事。简单的方法是:忽略它,接受请求仍将计算,直到服务器端请求处理器意识到其输出流已关闭并将失败。

如果你有一些重型操作确实需要很长时间才能完成,我会选择以块的方式进行服务器端工作 - 中间 - 检查是否仍然需要继续请求。任何新请求都可以设置同一用户的其他线程正在检查的标志。

在java线程级别上进行交互(例如Thread.stop等)并不是在应用程序逻辑中进行交互的好方法。但是,如果您有一些应用程序逻辑确定哪个用户需要执行哪个操作,并且每个操作都可以检查是否仍然需要,那么这可能对您有所帮助。你仍然会浪费几个周期,但不一定是全额。

此外,如果您在java线程级别进行交互,请记住,线程最有可能由应用程序服务器拥有,并在线程池中用于请求处理 - 因此您不应该使用它们(从外)。

答案 1 :(得分:0)

我认为你可以在服务器上做到这一点,但是如评论所暗示的那样,它会有点不切实际。

您需要一个跟踪

的数据结构(可能是HashMap)
  • 提出请求的用户
  • 为请求提供服务的当前Thread对象
  • 有助于识别请求的任何其他上下文内容

在对servlet的传入HTTP请求中,查阅查找表并查看是否已存储Thread对象。如果是,则stop the thread,并继续在当前线程中执行。在线程将内容返回给客户端之前,请务必从HashMap中删除Thread的条目。

这是一个相当复杂的情况。每当你处理并发时,你就冒着把事情搞得一团糟的风险。如果真的,我只会遵循这条路线,真的想要节省服务器端资源。否则,正如Aleks G建议的那样,仅使用AJAX取消客户端上的上一个调用可能会容易得多。