Java newFixedThreadPool解释

Java newFixedThreadPool解释,java,multithreading,wso2,Java,Multithreading,Wso2,我正在尝试诊断使用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 c

我正在尝试诊断使用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()

当作为线程池一部分的线程抛出异常时,它确实会被新的新线程替换。但是,它不会重试相同的操作。只有在需要执行更多任务时,线程池才能继续执行其工作,才会进行替换

通常情况下,当线程以这种方式终止时,会记录堆栈跟踪,但异常可能会在某个地方被吞没。您可以尝试在发送代码周围添加try-catch块,并显式记录任何异常,以进一步分析问题


不调用
shutdown
是可以的。

当线程池中的一个线程抛出异常时,它确实会被一个新的线程替换。但是,它不会重试相同的操作。只有在需要执行更多任务时,线程池才能继续执行其工作,才会进行替换

通常情况下,当线程以这种方式终止时,会记录堆栈跟踪,但异常可能会在某个地方被吞没。您可以尝试在发送代码周围添加try-catch块,并显式记录任何异常,以进一步分析问题

不调用
shutdown
是可以的

我正在对用户创建过程进行负载测试,在WSO2发送用户凭据配置邮件时,它正在向相同的电子邮件地址发送多封邮件,即使它们是唯一的

当我听到Java框架/应用程序服务器执行身份管理+线程池+奇怪的行为时,我立刻想到的是,大多数框架使用每用户线程模型(即:用户身份绑定到线程。如果切换线程,用户身份验证数据将丢失)。现在我不知道SO2的情况是否如此,但请参阅文档。这是“通常的怀疑”:线程本地身份验证机制无处不在

在Java文档中,它提到“如果一个线程在执行期间和关闭之前由于失败而终止,那么将创建一个新线程来代替它。” 这是否意味着如果电子邮件发送遇到错误,那么新线程将再次开始该过程

否。这意味着将创建一个新线程来处理其他提交的工作单元。但不会再次尝试失败的工作单元。就线程池而言,任务已经完成(有一个异常),并且已经完成了

另外,永远不要调用
threadPool.shutdown()

事实并非如此。您应该使您的
NotificationSender
类具有某种
close()
end()
方法。或者可以将它与一些WSO2生命周期回调联系起来(例如,在servlet上下文中,您有生命周期事件的侦听器,在Spring容器中,您有其他创建/销毁回调,…在您的上下文中工作的任何东西)。关闭线程池失败意味着某些线程将挂起,并且它们的资源永远不会释放。现在的线很便宜,但从长远来看,它们仍然会堆积起来,咬你一口。如果您确定在整个应用程序中只创建了一个
NotificationSender
,并且此对象的生命周期与您的应用程序相同,则可能是正常的。然后,从本质上说,关闭它与关闭应用程序是一样的,因此没有什么不好的事情发生

我正在对用户创建过程进行负载测试,在WSO2发送用户凭据配置邮件时,它正在向相同的电子邮件地址发送多封邮件,即使它们是唯一的

当我听到Java框架/应用程序服务器执行身份管理+线程池+奇怪的行为时,我立刻想到的是,大多数框架使用每用户线程模型(即:用户身份绑定到线程。如果切换线程,用户身份验证数据将丢失)。现在我不知道SO2的情况是否如此,但请参阅文档。这是“通常的怀疑”:线程本地身份验证机制无处不在

在Java文档中,它提到“如果一个线程在执行期间和关闭之前由于失败而终止,那么将创建一个新线程来代替它。” 这是否意味着如果电子邮件发送遇到错误,那么新线程将再次开始该过程

否。这意味着将创建一个新线程来处理其他提交的工作单元。但不会再次尝试失败的工作单元。就线程池而言,任务已经完成(有一个异常),并且已经完成了

另外,永远不要调用
threadPool.shutdown()

事实并非如此。您应该使您的
NotificationSender
类具有某种
close()
end()
方法。或者可以将它与一些WSO2生命周期回调联系起来(例如,在servlet上下文中,您有生命周期事件的侦听器,在Spring容器中,您有其他创建/销毁回调,…在您的上下文中工作的任何东西)。未能关闭线程