Java newFixedThreadPool解释

时间:2017-04-21 07:52:53

标签: 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 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 个答案:

答案 0 :(得分:1)

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

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

不调用shutdown就好了。

答案 1 :(得分:1)

  

我正在加载测试用户创建过程,并且在WSO2发送用户凭据配置邮件时,即使它们是唯一的,它也会将多个发送到同一个电子邮件地址。

好吧,当我听到Java框架/应用服务器进行身份管理+线程池+奇怪行为时,立即想到的是大多数框架都使用每个用户模型的线程(即:用户身份与线程。如果切换线程,则用户认证数据丢失)。现在我不知道SO2是否属于这种情况,但请参阅文档。这是“通常的嫌疑人”:线程本地认证机制无处不在。

  

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

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

  

此外,永远不要拨打threadPool.shutdown()

不是。您应该让NotificationSender课程采用某种close()end()方法。或者可以将它与一些WSO2生命周期回调联系起来(例如在servlet上下文中,你有生命周期事件的监听器,在Spring容器中,你有其他的创建/销毁回调,......在你的上下文中有效)。无法关闭线程池意味着某些线程会挂起,并且它们的资源永远不会被释放。线程现在变得相当便宜,但从长远来看,它们可能还会堆积起来并且让你陷入困境。如果您确定只在整个应用中创建一个NotificationSender,并且该对象的生命周期与您的应用相同,那么它可能只是有点。然后,基本上,关闭它与关闭应用程序是一样的,所以没有什么不好的事情发生。