我有一个 JavaScript 应用程序,它可以允许用户向我的 Tomcat 服务器发出多个重叠的只读请求,以便以后的请求应该取消并覆盖任何早期的请求。在请求到来之前,我可以禁用所有客户端控件,但我宁愿让它们保持启用状态,让用户随时单击,并取消以前的请求。
我想做的是取消除最新请求之外的所有请求,这样我的服务器就不会浪费时间完成永远不会看到的请求。我希望服务器中止它为该请求运行的线程,以减少服务器资源。
最好的方法是什么?
如果只是为了节省服务器 CPU 时间,客户端取消请求将无济于事。简单的方法是:忽略它,接受请求仍将计算,直到服务器端请求处理器意识到其输出流已关闭并且将失败。
如果您有一些确实需要很长时间才能完成的繁重操作,我会选择分块进行服务器端工作,并且 - 中间 - 检查请求是否仍需要继续。任何新请求都可以设置同一用户的其他线程正在检查的标志。
在 java 线程级别(例如 Thread.stop 等)上进行交互并不是在应用程序逻辑中进行交互的好方法。但是,如果您有一些应用程序逻辑来确定哪个用户需要完成哪个操作,并且每个操作都可以检查它是否仍然需要,那可能会对您有所帮助。你仍然会浪费几个周期,但不一定是全部。
此外,如果您在 java 线程级别上进行交互,请记住线程很可能归应用程序服务器所有,并在线程池中用于请求处理 - 因此您不应该(从外部)弄乱它们。
我认为您可以在服务器上执行此操作,但这会有点不切实际,正如评论中所暗示的那样。
您需要一个数据结构(可能是 HashMap)来跟踪
在对 servlet 的传入 HTTP 请求中,查阅查找表并确定是否已经存储了一个 Thread 对象。如果是,则停止线程,并在当前线程中继续执行。在线程将内容返回给客户端之前,请务必从 HashMap 中删除 Thread 的条目。
这是一个相当复杂的情况。任何时候你处理并发,你都冒着把事情搞砸的风险。如果您真的非常想节省服务器端资源,我只会遵循这条路线。否则,正如Aleks G所建议的那样,仅使用 AJAX 在客户端取消之前的调用可能会容易得多。