【问题标题】:starting a new thread in servlet在 servlet 中启动一个新线程
【发布时间】:2012-05-06 23:45:38
【问题描述】:

当请求到达处理文件上传的 servlet 时,在该 servlet 中使用new Thread(r).start() 启动一个新线程是一个好主意,该线程将处理上传的文件附带的另一条数据。我希望这可以同时处理这两项工作。

【问题讨论】:

  • 除非你使用线程池,否则我会反对它。或者,Servlet 3 现在有异步服务调用,为什么不探索一下呢?
  • 您使用的是哪个应用服务器?它是否为长时间运行的任务提供某种支持?
  • @BigMike Glassfish 3.1.1

标签: java multithreading servlets web


【解决方案1】:

这不仅是一个坏主意,而且也行不通。原因如下:您的文件上传请求最终会命中doPost() 方法。只要您使用此方法,容器就会保持连接打开。一旦您从该方法返回(并且如果您决定在单独的线程中处理传入数据,doPost() 将提前完成)容器假定您已完成请求并将关闭连接。从客户端的角度来看,上传被服务器中断了。而且由于线程的异步特性,中断会随机发生。

相信我,一些用户已经体验过:HttpServletResponse seems to periodically send prematurely。

此外,每个请求都启动新线程是个坏主意,因为它的扩展性很差(某些规范甚至禁止它)。您可以做的是使用 Servlet 3.0 异步请求并异步处理上传,但最好使用一些线程池。另见:Why create new thread with startAsync instead of doing work in servlet thread?。

【讨论】:

  • ... 坏主意,除非您需要执行一些长时间运行的 CPU 密集型任务。
  • @Tomasz Nurkiewicz 即使我将新线程的工作保留在该 servlet 的 doPost() 方法中?
  • @Tomasz Nurkiewicz 可以在这个 servlet 的 post 方法中从线程的 run 方法向另一个 servlet 分派一个新请求吗?
  • 你激发了我的好奇心 :) 我会尝试一些异步的东西,但我对客户端有一些不好的感觉。 (如何返回上传结果?)。
  • @grassPro: 如果你的线程在doPost() 内运行(你正在使用join() 等待线程结果?)线程的意义何在?
【解决方案2】:

Servlet 由 webserver 在新线程中隐式运行,因此每当任何请求命中 servlet 时,它将在不同的线程中执行。我没有预见到自己创建新线程的理由

【讨论】:

  • 也许只是为了不让客户端冻结(如果线程很耗时?)
  • 因此用户不必等待 servlet 完成上传
  • @BigMike 但通常情况下,我们不会赋予 servlet 多重职责,如果这个 servlet 正在处理文件上传,那么您无能为力,所以我会说与其创建新线程,不如启动一个来自客户端的全新请求。
【解决方案3】:

在 Servlet 中启动新线程没有什么问题(不像 EJB),所以是的,没关系。

编辑:第二个想法@Tomasz Nurkiewicz 是对的。文件上传将停止。

【讨论】:

  • 不对,在并发环境下写线程需要管理。
  • 只要线程不使用任何非局部变量(servlet 中的字段)就没有问题。我假设一切都发生在 doGet/doPost 方法中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多