【问题标题】:using threads in servlets在 servlet 中使用线程
【发布时间】:2012-02-18 14:55:49
【问题描述】:

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

【问题讨论】:

  • 即使它不是明确非法的,我也会尽量避免在 servlet 中创建线程。结果可能无法预测或取决于您使用的容器。您能否详细解释一下您的要求以及为什么需要创建自己的线程?不过一般来说,您的代码需要是线程安全的,因为容器可能会从不同的线程调用相同的 servlet 对象。 servlet 规范中有很多关于这方面的信息。
  • 问题是我正在阅读日志文件,然后根据严重性发送邮件。这个过程不断发生,但我注意到有时它会丢失邮件。所以我想使用不同的线程对于邮件部分,如果我必须同时读取多个文件怎么办。不使用线程如何实现??

标签: multithreading jakarta-ee servlets


【解决方案1】:

你在问两个不同的问题:

我很困惑我们是否应该在 servlet 中创建自己的线程,因为 他们内部有线程机制?。

通常,您不应在 Java EE 应用程序中启动线程。如果您需要单独的线程,请确保使用您的应用程序知道的调度程序服务,以便在应用程序关闭时有机会关闭线程。石英是最常用的。

如果是,我们如何确定程序线程是否安全?如何 在 servlet 中实现线程安全机制。

Servlet 就像任何其他 Java 类一样。查找有关线程安全的教程或阅读Java Concurrency in Practice

【讨论】:

  • 我正在使用 Timer 类,当我停止部署我的程序的 tomcat 服务器时,我无法停止线程
  • @raghav 计时器是一个古老的遗物。您应该切换到 Java 1.5 中引入的 ExecutorService 接口。 Executors.newScheduledThreadPool(poolSize) 应该是你需要的
  • 这样你就可以在你的 web 应用关闭时调用 ExecutorService.shutdown()。
  • @Sean Patrick Floyd:you should not start threads in a JEE application.你遇到过容器问题吗?我在 Tomcat 中多次使用线程都没有问题。
【解决方案2】:

根据您在评论中写的内容,我了解到您有一组线程持续监控日志文件并在日志中发现有趣的内容时发送电子邮件。

第一个问题:为什么这是一个 servlet?有网页界面吗?这是干什么用的?

对于日志扫描部分,我会将其实现为 servlet 容器之外的单独进程。对于该进程发现的所有需要​​发送到某处的内容,我将向 JMS 队列添加一条消息。然后我将创建一个消息驱动 bean 来接收来自该队列的消息并将它们作为电子邮件发送。 (这确实是一个集成问题,将消息从 JMS 转换为电子邮件,您可能想研究像 Mule 这样的东西来解决这个问题。

至于如何将它与您的servlet集成,这取决于您的servlet除了扫描日志之外还做了什么(我想它为用户提供了某种界面)

通过这种设计,您可以选择在将来重新编写生成日志的程序。第一个程序最好将有趣的消息直接放在 JMS 队列上,而不是让一个程序编写日志和另一个程序解析日志。换句话说,您将来可以更改架构的日志生成部分,而无需重新编写邮件发送部分。

【讨论】:

  • 是的,你是对的。如果出现问题,我正在使用计时器扫描日志文件并发送邮件。现在的问题是,为什么这是一个 servlet,所以当我想知道它运行良好时,我可以得到响应。现在的问题是,当我使用新线程发送邮件时,它会出现内存泄漏问题,因为当我停止应用程序或服务器时它无法停止线程。所以你是说我应该为此使用 JMS 队列,对吧?
  • 如果您让实现日志扫描,您的日志扫描线程不会干扰应用服务器线程。在实现与 JMS 的通信时,应用程序服务器会为您处理线程并仅在有实际消息时调用您的消息处理代码。为了监视外部日志扫描过程,它可以定期发送“i-am-alive”消息,并且 servlet 可以只报告最后一次“i-am-alive”发生的时间(并且它也可以明显地报告其他事情,例如收到的消息数和发送的邮件数)
【解决方案3】:

我也有类似的担忧。

只有EJB 规范不允许从应用程序创建线程。

可以从 servlet 启动线程。
我做了很多次都没有问题,但老实说我不是 100% 确定:

  • 容器允许这样做违反了标准

  • 所有容器都允许。

但是在 Tomcat 中,我从来没有遇到过从 servlet 启动线程的问题。

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

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

【讨论】:

  • 来自 servlet-spec(3.0 版,第 1.2 章):“例如,高端应用服务器可能会限制 Thread 对象的创建,以确保容器的其他组件不会受到负面影响。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多