2016-06-12 5 views
1

스프링에서 JavaMailSenderImpl을 사용하여 웹 응용 프로그램에서 전자 메일을 보내고 있습니다. 이 인스턴스는 하나만 만들었습니다 (실제로 스프링 콩을 사용하여 만들어지고 싱글 톤인 다른 객체에 의해 사용됩니다).JavaMailSenderImpl은 스레드로부터 안전합니까?

그래서 JavaMailSenderImpl은 스레드로부터 안전한가요? 내 응용 프로그램에서 여러 스레드가 동시에 mailSender를 사용하는 경우 모든 경쟁 조건이 발생합니까?

+0

예 일단 구성된 경우 스레드로부터 안전합니다. –

+0

@ M.Deinum 나는 소스 코드를 보았지만 똑같은 줄 알았다. 당신이 정교하게 대답하고 내가 그것을 받아 들일 수 있도록 대답을 추가 할 수 있습니까? 여러 스레드가 동시에 메일을 보낼 수있는 방법에 대해 설명하면 좋을 것입니다. – kiran

답변

3

JavaMailSenderImpl은 스레드 안전 이 구성됩니다.

실제 작업을 수행하는 doSend 메서드를 살펴보십시오. 메소드 로컬 변수 만 포함합니다 (각 호출 스레드/스택이 자체 인스턴스를 가짐). 일부 기능을 추가하는 send 메서드에도 동일하게 적용됩니다.

getSession과 같은 메서드는 synchronized이므로 단일 스레드 만 해당 메서드에 액세스 할 수 있습니다.

스레드 안전성을 보장하는 가장 큰 이유는 (거의) 변경 가능한 공유 상태가없고 사실 synchronized 인 단일 변경 가능 공유 상태 (Session)가 있다는 것입니다.

다음으로는 프로덕션 시스템에서 12 년 넘게이를 싱글 톤 방식으로 사용하고 있으며 동시성에 문제가 없었습니다. 그리고 우리는 고도의 동시 응용 프로그램에서이 도구를 사용했습니다. (또한 스프링 배치 및 스프링 통합과 같은 다른 프레임 워크 구성 요소가 JavaMailSender API를 사용하는 방식이기도합니다).

+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')마다 여러 번 호출 될 수 있습니다.따라서, 그 thread가 spring-bootstrap thread보다 전에 기동했다면, happen-before edge가 없기 때문에 getUsername으로부터 null을 읽을 수 있습니다. (저는 여러분에게 동의합니다. 특히 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), getters는 첫 번째 동기화 지점 전에 호출되므로, 스레드 안전, – SerCe

관련 문제