2016-06-12 8 views
1

Я использую JavaMailSenderImpl из источника для отправки писем в своем веб-приложении. Я создал только один экземпляр этого (на самом деле он используется другим объектом, который создается с использованием весенних бобах и является одиночным).Является ли JavaMailSenderImpl весенней нитью безопасной?

Итак, вопрос в том, является ли JavaMailSenderImpl потокобезопасным? В моем приложении, когда несколько потоков используют mailSender одновременно, это приведет к любым условиям гонки?

+0

Да, это потокобезопасность после постройки. –

+0

@ M.Deinum Я так же думал об исходном коде, но не уверен. не могли бы вы рассказать и добавить ответ, чтобы я мог его принять. Будет замечательно, если вы объясните, как несколько потоков могут отправлять письма одновременно. – kiran

ответ

3

Да JavaMailSenderImpl является потокобезопасным раз строится.

Посмотрите на метод doSend, который выполняет фактическую работу. Он содержит только локальные переменные метода (поэтому каждый вызывающий поток/стек имеет свой собственный экземпляр). (То же самое относится к методу send, который добавляет некоторые функции).

Методы, подобные getSession, равны synchronized, поэтому только один поток может иметь доступ к этому методу.

Самая большая вещь, которая делает его потокобезопасной, заключается в том, что существует (почти) нет измененного общего состояния и единственное изменяемое общее состояние (Session), что есть .

Рядом с тем, что использовалось более 12 лет в производственных системах одномодовым способом и никогда не возникало проблем с параллелизмом. И да, мы использовали его в высококонкурентных приложениях. (И так же, как и другие компоненты инфраструктуры, такие как Spring Batch и Spring Integration, используют API JavaMailSender).

+0

. Посмотрите на заказ [полевая загрузка] (https://github.com/spring-projects/spring-framework/blob/master/spring-context-support/src/main/java/org /springframework/mail/javamail/JavaMailSenderImpl.java#L491). Имя пользователя и пароль загружаются перед вызовом 'getSession', поэтому не происходит - до края здесь, даже если существует некоторая точка синхронизации после построения. – SerCe

+0

Правильно ... Но это то, что вам не следует делать в первую очередь ... И я утверждаю, что безопасно использовать ПОСЛЕ конструирования ... Весенние бутстрапы в одном потоке. Также 'getUsername' и' getPassword' вызывается один раз, а затем используется локально не глобально. То же самое относится и к другим классам фреймворка (все они содержат примечание: ** Экземпляр этого класса после потоковой записи является потокобезопасным. **.). –

+0

@ m-deinum, но 'connectTransport' может вызываться несколько раз из разных потоков (каждая' doSend').Итак, если этот поток начался до потока spring-bootstrap, он может читать значение null из 'getUsername' из-за отсутствия края до начала. (Я согласен с вами в том, что это очень непрактичный случай, особенно для x86, но я не вижу никакого доказательства правильности JMM здесь) – SerCe

0

Нет, это не так.

Хотя it has некоторая синхронизация в исходном коде, поля, такие как пользователь, пароли не имеют доступа к синхронизации. Итак, если вы вызываете setUsername в одном потоке, нет никакой видимости для других тем.

+0

Я создаю объект только один раз, используя весну и устанавливая все необходимые поля для аутентификации почтового сервера и javaMailProperties. Я не меняю их снова. После создания объекта несколько потоков (причал) используют его для отправки писем параллельно. Будет ли это проблемой? Я специально спрашиваю о отправке почты. – kiran

+0

[Здесь] (https://github.com/spring-projects/spring-framework/blob/master/spring-context-support/src/main/java/org/springframework/mail/javamail/JavaMailSenderImpl.java#sourcegraph&def = JavaArtifact/org.springframework/spring-context-support/-/org/springframework/mail/javamail/JavaMailSenderImpl: type/getSession & L151-156), геттеры вызываются до первой точки синхронизации, поэтому, согласно случаям, thread safe, – SerCe

 Смежные вопросы

  • Нет связанных вопросов^_^