Servlet中的线程和并发处理

5
我有一个web应用程序,从数据库中检索出(大量)结果列表,然后需要逐个查看每个结果,并丢弃“无效”的结果。使结果“无效”的参数是动态的,我们无法将工作传递给数据库。
因此,一个想法是创建一个线程池和ExecutorService,并同时检查这些结果。但我不断看到人们说“哦,在servlet中禁止生成线程”或“那只是一个坏主意”。
所以,我的问题是:我应该怎么办?我在servlet 2.5容器中,因此所有关于3.0规范的异步好处对我来说都不可用。编写一个通过JMS与之通信的单独服务似乎过度。
在这里寻求专家建议。
Jason

不完全是重复的:https://dev59.com/W2865IYBdhLWcg3wkfgW - Samuel Edwin Ward
也许你可以创建一个基于参数哈希的缓存。当然,这取决于你有多少可能性,但这可能会有所帮助。 - Alexandre FILLATRE
有没有办法将您的参数传递到数据库查询中?拉回您抛弃的数据可能不是一个好方法。 - Nathan Hughes
也许,回答这个问题的一些人也能回答这个问题:https://dev59.com/in7aa4cB1Zd3GeqPxf1g - pWoz
听起来像是后台任务。你在做什么与网络有关的事情?你是通过请求传递参数吗?你只是在网页上显示结果吗?我觉得这里缺少了网络角色。 - Mani
显示剩余3条评论
5个回答

5
胡言乱语。JEE规范中有很多“不应该”和“你不应该”的字眼。然而,与之相反的是,Servlet规范中没有这样的规定。Servlet规范比较“野蛮西部”,它没有像JEE规范那样深入探讨实际操作方面的问题。
我从未见过一个JEE容器(无论是像Tomcat/Jetty这样的纯servlet容器,还是像Glassfish/JBoss这样的完整容器)会阻止我自己启动一个线程。虽然WebSphere据说是相当臭名昭著的,但我并没有使用过WebSphere。
如果创建自管理的线程的概念让您感到不适,那么完整的JEE容器内部都有一个正式的“WorkManager”,可以用来拉出线程。他们只是以不同的方式公开它们。这是获取线程的更加“按照规范”的机制。
但是,老实说,我也不会费心。您可能会更成功地使用标准类库中的执行程序。如果您用太多线程饱和了系统,一切都失控了,那么这就是您的责任。不要做那些事情(商标)。
至于异步解决方案是否适用,我不好发表评论。从你的帖子中无法确定。但是你的问题是关于线程和Servlet的。
只是去做吧。意识到它“可能不具备可移植性”,正确地做(使用执行程序),承担责任,容器不会更聪明,也不会在意。

我考虑过Weblogic的WorkManager,但想要一个更具可移植性的解决方案。 - Jason

2

看起来并发不会在这里给你带来太大的帮助。除非检查每个条目非常昂贵,否则使检查并发化不会加速事情。您的瓶颈是通过数据库连接传递结果集,即使您没有在处理servlet,也无法将其多线程化。


2

并没有什么能阻止你从你的Servlet中触发ThreadPool,挑战在于获取结果。如果Servlet调用希望从你提交到TreadPool的任务中得到某些结果,那么你最终将会被阻塞,等待TreadPool完成工作以便你可以对doGet/doPut调用进行响应。

另一方面,如果你设计你的服务,例如:doPut提交任务给线程池,但是获得一个“句柄”或其他唯一标识来返回任务给客户端,那么客户端可以通过一些doGet API“轮询”句柄以查看任务是否已完成。当任务完成时,客户端可以获得结果。


2

这是完全可以的,也很合适。我已经使用了数不清的Servlets,在不同的容器上使用线程池,没有任何问题。

EJB容器(如JBoss)倾向于警告不要生成线程,但这是因为EJB保证Bean的实例仅由一个线程调用,并且某些设施依赖于此,因此您可能会通过使用自己的线程来搞砸它。在Servlet中没有这样的依赖关系,因此您无法以这种方式弄乱任何东西。

即使在EJB容器中,只要不从自己的线程中与EJB设施交互(例如调用),您也可以使用线程池并且不会出现问题。


我们没有使用EJB(谢天谢地)。我们可以在一组Tomcat实例集群上运行整个混乱系统,但是客户被Oracle的销售人员迷惑了。 - Jason

1
注意使用servlet/线程时,需要确保servlet的成员变量是线程安全的。
技术上讲,你可以在servlet中使用线程池进行一些后处理,但是如果你创建了一个静态线程池,例如20个线程,并且有50个客户端同时访问你的servlet,那么你可能会自己给自己惹麻烦,因为30个客户端会等待(这取决于后处理所需时间)。

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