3

我正在使用 Spring 中的 JavaMailSenderImpl 在我的 Web 应用程序中发送电子邮件。我只创建了一个实例(实际上它被另一个使用spring beans创建的对象使用,并且是一个单例)。

所以问题是,JavaMailSenderImpl 是线程安全的吗?在我的应用程序中,当多个线程同时使用 mailSender 时,会导致任何竞争条件吗?

4

3 回答 3

9

是的,一旦构建,它JavaMailSenderImpl就是线程安全的。

看看doSend执行实际工作的方法。它仅包含方法局部变量(因此每个调用线程/堆栈都有自己的实例)。(这同样适用于send添加一些功能的方法)。

像这样的方法getSession只有synchronized一个线程可以访问该方法。

使它成为线程安全的最重要的事情是(几乎)没有可变的共享状态,而唯一的可变共享状态(the Session)是synchronized.

除此之外,它已经在生产系统中以单例方式使用了超过 12 年,并且从未遇到过任何并发问题。是的,我们在高度并发的应用程序中使用了它。(这也是 Spring Batch 和 Spring Integration 等其他框架组件使用JavaMailSenderAPI 的方式)。

于 2016-06-13T06:36:18.893 回答
0

它是线程安全的,但值得补充的是,它只能支持有限数量的并发调用。当我的第 4 个线程调用 sendMail 函数时,我收到以下错误:

org.springframework.mail.MailSendException:失败的消息:com.sun.mail.smtp.SMTPSendFailedException:432 4.3.2 STOREDRV.ClientSubmit;超出发件人线程限制 [主机名=***]。因此,您应该捕获运行时异常并将其记录下来,否则它只会被运行该线程的执行程序服务吞没。  

于 2019-10-11T17:52:56.767 回答
-1

不它不是。

尽管它的源代码中有一些同步,但用户、密码等字段没有同步访问权限。因此,如果您调用setUsername一个线程,则无法保证其他线程的可见性。

于 2016-06-12T18:11:21.767 回答