我目前正在构建一个基于java-servlet的Web应用程序,该应用程序应该为很多用户提供服务(不要问我“有多少”:-) - 我还不知道)
但是,在使用应用程序时,可能会在服务器端进行一些长时间处理。 为了避免糟糕的UI响应,我决定将这些处理操作移到自己的线程中。 这意味着一旦用户登录,就会发生1-10个线程在后台运行(每个用户!)。
我曾经听说在Web应用程序中使用多个线程是一个“坏主意”。
这是真的,如果是的话:为什么?
更新:我忘了提到我的应用程序严重依赖于ajax调用。每个用户操作都会导致新的ajax调用。因此,当主servlet线程忙时,ajax调用需要很长时间才能处理。这就是我想使用多线程的原因。
答案 0 :(得分:5)
答案 1 :(得分:2)
“坏主意”不是多线程。 Java EE最初编写,因此多线程掌握在app服务器手中,因此不鼓励用户启动自己的线程。
我认为您真正想要的是长时间运行任务的异步处理,因此用户无需等待它们继续完成。
您可以使用JMS执行此操作,并保持在Java EE着色书中。我认为现在自己做更安全,因为java.util.concurrent
包中有新的类和结构。
这仍然不是一件容易的事。多线程代码并非易事。但我认为它比以前在Java中更容易。
部分问题可能是你要求servlet做得太多。 Servlet应该监听HTTP请求并协调从其他类获取响应,而不是自己进行所有处理。也许你的servlet告诉你是时候重构了一下。这将有助于您的测试,因为您将能够在不运行servlet / JSP引擎的情况下对这些异步类进行单元测试。
通过HTTP调用服务不需要阻止。如果服务可以返回一个令牌,即FedEx,告诉应用程序何时以及如何获得响应,则没有理由说服务无法异步处理。这是您应该从客户端隐藏的服务的实现细节。
答案 2 :(得分:1)
1。
很棒的主意。
这并不常见,但没有错
如果您认为需要异步任务以获得更好的用户体验。只需使用它。
2。
你需要小心。
2.1。
创建和销毁线程会给服务器增加很多开销
您最好使用执行程序,例如java.util.concurrent.ThreadPoolExecutor
。
2.2。
不要只使用Executors.newFixedThreadPool()
。这是为初学者和隐藏危险的细节
您需要知道ThreadPoolExecutor的边缘行为,并正确配置它。
答案 3 :(得分:0)
如果应用程序需要它,那么我说继续执行后台线程,但是,由于您不知道您将拥有多少用户,因此您承担的风险很大,您将使您的服务器瘫痪。如果它们适用于您的情况,您可以考虑一些替代方案。您可以完全脱机运行后台任务,例如在批量工作?你能限制每个登录用户需要的线程数吗?如何将后台线程的结果返回给用户?
答案 4 :(得分:0)
这主要有三个主要原因:
我认为最好的解决方案是设计你的应用程序,这样它就不会创建那么多的后台线程。
但是如果你坚持或真的需要它,请尝试使用Java EE message driven beans(MDB)并让你的servlet使用JMS调用它,就像@duffymo所说的那样。
挑战在于如何在MDB和用户会话之间进行通信。也许你的servlet可以创建一个JMS queue或topic并将它发送给MDB以供他们回复,但我不知道JMS连接的servlet端是否可以被钝化和恢复。
另一种形式的通信是JNDI或外部数据库或文件,但这需要轮询,这可能没有响应或CPU过多。