我正在使用Spring的JavaMailSenderImpl在我的Web应用程序中发送电子邮件。我只创建了一个这样的实例(实际上它是由另一个使用spring bean创建并且是单例的对象使用的。)
所以问题是,JavaMailSenderImpl是否是线程安全的?在我的应用程序中,当多个线程同时使用mailSender时,它是否会导致任何竞争条件?
答案 0 :(得分:6)
是JavaMailSenderImpl
一旦构建,它就是线程安全的。
查看执行实际工作的doSend
方法。它只包含方法局部变量(因此每个调用线程/堆栈都有自己的实例)。 (这同样适用于添加某些功能的send
方法)。
像getSession
这样的方法是synchronized
,因此只有一个线程可以访问该方法。
使线程安全的最重要的事情是(几乎)没有可变共享状态和单个可变共享状态(Session
)存在synchronized
。
接下来,它已经以单身方式在生产系统中使用了超过12年,并且从未遇到任何并发问题。是的,我们在高度并发的应用程序中使用它。 (它也是Spring Batch和Spring Integration等其他框架组件使用JavaMailSender
API)的方式。
答案 1 :(得分:0)
不,不是。
虽然it has在源代码中有一些同步,但用户,密码等字段没有同步访问权限。因此,如果您在一个线程中调用setUsername
,则其他线程没有可见性保证。
答案 2 :(得分:0)
它是线程安全的,但值得一提的是,它仅支持有限数量的并发调用。当我的第四个线程调用sendMail函数时,出现以下错误:
org.springframework.mail.MailSendException:失败消息:com.sun.mail.smtp.SMTPSendFailedException:432 4.3.2 STOREDRV.ClientSubmit;发件人线程限制已超过[主机名= ***]。因此,您应该捕获运行时异常并将其记录下来,否则它只会在运行该线程的执行程序服务中被吞噬。