有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java newFixedThreadPool解释

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

共 (2) 个答案

  1. # 1 楼答案

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

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

    不调用shutdown是可以的

  2. # 2 楼答案

    I am load testing the user creation process, and at the point where WSO2 sends a User credentials configuration mail it is sending multiple to the same email address even though they are unique.

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

    In the Java docs it mentions "If a thread terminates due to failure during execution and prior to shutdown, a new thread is created to take its place." Does this mean that if the email send encounters an error then a new thread will begin the process again?

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

    Also, is it ok to never call threadPool.shutdown()

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