我正在尝试使用WSO2身份管理来诊断我遇到的问题。
package org.wso2.carbon.identity.mgt;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* email sender this creates a new task in thread pool for each email sending request
*/
public class NotificationSender {
private static ExecutorService threadPool = Executors.newFixedThreadPool(5);
NotificationSendingModule module;
/**
* creates and submits a task to the thread pool
*
* @param module email sending module as task
*/
public void sendNotification(NotificationSendingModule module) {
threadPool.submit(module);
}
public NotificationSendingModule getModule() {
return module;
}
}
我正在加载测试用户创建过程,并且在WSO2发送用户凭据配置邮件时,即使它们是唯一的,它也会将多个发送到同一个电子邮件地址。
我从未使用过Java但熟悉C#,因此能够毫无问题地阅读代码,我的问题是:
在Java文档中,它提到“如果一个线程在执行期间和关闭之前由于失败而终止,则会创建一个新线程来代替它。”
这是否意味着如果电子邮件发送遇到错误,那么新线程将再次开始该过程?
我想也许发送电子邮件是错误的,所以创建了一个新的线程,但是无论如何都没有将结果记录到结果中。
此外,永远不能打电话
threadPool.shutdown()
答案 0 :(得分:1)
当作为线程池一部分的线程抛出异常时,它确实被替换为新的新线程。但是它不会重试相同的操作。只进行替换,以便在需要执行更多任务时,线程池可以继续工作。
通常,当线程以这种方式终止时,会记录堆栈跟踪,但可能会在某处吞下异常。您可以尝试在发送代码周围添加try-catch块并明确记录任何异常以进一步分析问题。
不调用shutdown
就好了。
答案 1 :(得分:1)
我正在加载测试用户创建过程,并且在WSO2发送用户凭据配置邮件时,即使它们是唯一的,它也会将多个发送到同一个电子邮件地址。
好吧,当我听到Java框架/应用服务器进行身份管理+线程池+奇怪行为时,立即想到的是大多数框架都使用每个用户模型的线程(即:用户身份与线程。如果切换线程,则用户认证数据丢失)。现在我不知道SO2是否属于这种情况,但请参阅文档。这是“通常的嫌疑人”:线程本地认证机制无处不在。
在Java文档中,它提到“如果一个线程在执行期间和关闭之前由于失败而终止,则会创建一个新线程来代替它。” 这是否意味着如果电子邮件发送遇到错误,那么新线程将再次开始该过程?
没有。这意味着将创建一个新线程来处理已提交的其他工作单元。但失败的工作单位将不会再次尝试。就线程池而言,任务已完成(有例外),并且已完成任务。
此外,永远不要拨打
threadPool.shutdown()
不是。您应该让NotificationSender
课程采用某种close()
或end()
方法。或者可以将它与一些WSO2生命周期回调联系起来(例如在servlet上下文中,你有生命周期事件的监听器,在Spring容器中,你有其他的创建/销毁回调,......在你的上下文中有效)。无法关闭线程池意味着某些线程会挂起,并且它们的资源永远不会被释放。线程现在变得相当便宜,但从长远来看,它们可能还会堆积起来并且让你陷入困境。如果您确定只在整个应用中创建一个NotificationSender
,并且该对象的生命周期与您的应用相同,那么它可能只是有点。然后,基本上,关闭它与关闭应用程序是一样的,所以没有什么不好的事情发生。