2012-01-25 53 views
2

我很困惑,如果我们应该在servlet中创建自己的线程,因为它们在内部具有线程机制 ?.如果是,我们如何确保程序线程安全?如何在servlet中实现线程安全机制。在servlets中使用线程

+1

尽管它没有明确的非法,我会尽量避免在servlet中创建线程。结果可能无法预测,或取决于您使用的容器。你能否更详细地解释你的需求以及为什么你需要创建自己的线程?一般来说,你的代码需要是线程安全的,因为容器可能会从不同的线程调用同一个servlet对象。在servlet规范中有很多这方面的信息。 –

+0

事情是我正在阅读日志文件,然后根据严重程度发送邮件。这个过程正在不断发生,但我注意到有时它缺少邮件。因此,我想为邮件部分使用不同的线程,以及如果我必须在山姆时间读取多个文件。如何在不使用线程的情况下实现这一目标? – Rookie

回答

1

从你在评论中写的内容可以看出,如果在日志中发现了某种间歇性事件,你就有一组线程持续监视日志文件并发送电子邮件。

第一个问题:为什么这是一个servlet?有没有web-gui?这用于什么?

对于日志扫描部分,我会将它作为一个单独的进程实现在servlet容器之外。对于需要发送到某个地方的所有过程,我会将消息添加到JMS队列中。然后,我将创建一个消息驱动bean来接收来自该队列的消息并将它们作为电子邮件发送。(这实际上是一个集成问题,将消息从JMS转换为电子邮件,您可能希望查看类似Mule的内容来解决此问题)。

至于如何将它与你的servlet整合,这取决于你的servlet确实除了扫描日志(我想它提出了某种界面的用户)

采用这种设计的东西,你可以选择重新编写将来生成日志的程序。第一个程序不是只有一个程序写入日志和另一个程序解析日志,而是直接在JMS队列上放置中间消息。换句话说,您可以在将来更改您的架构的日志生成部分,而无需重新编写邮件发送部分。

+0

是的你是对的。我正在使用定时器扫描日志文件,并在发生问题时发送邮件。 现在的问题,为什么这是一个servlet,所以当我想知道它运行良好时,我可以得到响应。 现在的事情是当我发送邮件使用新线程它给内存泄漏的问题,因为它是无法停止线程时,我停止应用程序或server.so你说我应该使用JMS队列,这是正确的? – Rookie

+1

如果您让实施日志扫描,则您的日志扫描线程不会干扰应用程序服务器线程。在实现与JMS的通信时,应用程序服务器会为您处理线程,并仅在存在实际消息时才调用您的消息处理代码。为了监视外部日志扫描过程,它可以定期发送“我还活着”的消息,并且该小服务程序可以报告何时发生最后一个“我还活着”(并且它可能会明显地报告其他事情,例如收到的消息数量和发送的邮件数量) –

1

我也有类似的关注。

只有EJB规范禁止从应用程序创建线程。

可以从servlet启动线程。
我已经没有任何问题,但做了很多次,说实话我不是100%肯定:

  • 这是由容器允许的,但违反标准

  • 它被所有容器所允许。

但在Tomcat中,我从来没有从servlet开始线程的问题。

您可以像在每个多线程程序中一样使线程安全。

您将使用Java提供的所有可用结构进行同步。

+2

从servlet规范(版本3.0,第1.2章):“例如,高端应用程序服务器可能会限制创建一个Thread对象,以确保容器的其他组件不会受到负面影响。” –

2

你问两个不同的问题:

我是否应该让我们自己的线程在servlet或不糊涂,因为 他们内部的线程机制?

通常情况下,您不应该在Java EE应用程序中启动线程。如果您需要单独的线程,请确保使用应用程序知道的Scheduler Service,以便在应用程序关闭时有机会关闭线程。石英是大部分时间使用的。

如果是的话我们如何确定程序线程是否安全?如何到 在servlets中实现线程安全机制。

Servlets和其他任何Java类一样。查找关于线程安全的教程或阅读Java Concurrency in Practice

+0

我正在使用Timer类,当我停止部署我的程序的tomcat服务器时,我无法停止线程 – Rookie

+1

@raghav Timer是一个古老的遗迹。您应该切换到Java 1.5中引入的ExecutorService接口。 ['Executors.newScheduledThreadPool(poolSize)'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newScheduledThreadPool%28int%29)应该是你需要的 –

+0

这样,您可以在关闭Web应用程序时调用ExecutorService.shutdown()。 –