2011-03-23 148 views
5

我正在部署在Tomcat中的Web应用程序上工作。我们在客户端使用Spring,Hibernate,GWT)。创建线程在Tomcat中部署的Web应用程序

此应用程序的功能之一是在任何实体创建,更新或删除时向用户发送警报(电子邮件)。 (用户可以即时添加警报,因此需要处理一些事项 - 决定通过电子邮件通知哪些用户)。

警报机制理想情况下应该是异步的,它应该会影响CRUD操作的性能。

我想到的第一件事就是创建一个线程并拥有一个阻塞队列。线程保持轮询阻塞队列来查看它是否有任何事件。但是在web应用程序中创建线程是许多容器所不鼓励的。

有人建议/建议 - 这是做到这一点的正确方法吗?或者有更好的方法来做同样的事情。

任何指针将不胜感激。

由于提前, 萨钦

+0

只是不不要忘记将线程标记为守护程序线程,因此它们不会阻止Tomcat干净地关闭。 – Daniel 2011-03-23 14:39:03

回答

7

在容器中创建线程的限制实际上只是一个建议,以防止没有经验的开发人员在脚下自己拍摄。没有任何容器实际上禁止你这样做。使用java.util.concurrent类,创建线程应该不太容易出错,我不会担心这个限制太多。

如果您的要求很简单,只需在ServletContextListener中创建单个线程/ runnable即可。创建并启动线程contextInitialized()并关闭它在contextDestroyed()。 。使用由Executors.newSingleThreadScheduledExecutor()创建的ScheduledExecutorService。您传递给Executor的Runnable将从BlockingQueue中读取。

如果您的需求发生变化,您需要更复杂的东西,您可能需要查看JMS/MDB或Quartz等调度程序。

+0

谢谢您的回复。 – Sachin 2011-03-23 15:00:18

+1

这不仅仅是对缺乏经验的开发人员的建议。重点是阻止在旨在管理资源的环境中使用非托管资源。它在Web容器中是允许的,但是有一些提供托管线程的方法可以在这种环境下更好地工作。作为一个附注,EJB容器甚至不允许它。 – Robin 2011-03-23 15:09:37

+0

请看这个例子: http://java-by-ash.blogspot.com/2012/07/threads-in-java-web-application.html – ThreaT 2012-07-23 11:58:24

1

你可以使用一个调度程序来定期运行的作业或使用Spring相当于它们由它执行队列轮询您的容器中执行消息驱动Bean(some documentation on JMS and Spring)的。

+0

谢谢托马斯您的快速回复。我们正在考虑使用AOP并截获所有服务级别的CRUD调用,并在成功完成后更新ArrayBlockingQueue。如果我使用调度程序,拦截所有服务级别CRUD调用的Aspect如何通知调度程序?你能否提供一些Spring相当于MDB的更多细节(链接等)。再次感谢 – Sachin 2011-03-23 14:21:49

+0

好吧,我已经添加了一个链接,你检查了吗?至于调度程序,它应该定期运行(例如在1分钟左右),检查未决警报并发送它们。一个这样的调度器是[Quartz](http://www.quartz-scheduler.org/)。 – Thomas 2011-03-23 14:50:51

+0

谢谢吨Thoman。非常感谢您的回复... – Sachin 2011-03-23 14:59:43

0

有办法做到这一点,最简单的(除了简单地创建一个非托管线程)是使用commonj WorkManager。当然,你可以走简单的线程路线,但是它在你使用的环境中有缺点(如链接所述)。

1

您可以尝试使用Spring 3.x异步方法调用。来电方法会立即返回,并在实际执行异步发生

的applicationContext:

<task:annotation-driven executor="asyncExecutor" mode="aspectj"/> 
<task:executor id="asyncExecutor" pool-size="${executor.poolSize}"/> 

在你的bean:

@Async 
public void sendEmail(...) { 
// ... 
} 

请参考Spring文档中作进一步的细节:Spring 3.x Task Execution and Scheduling

相关问题