System.out.println의 다중 스레드 출력이 인터리브 됨
여러 스레드가 동기화없이 System.out.println (String)을 호출하면 출력이 인터리브 될 수 있습니까? 아니면 각 줄의 쓰기가 원자 적입니까? API는 이 가능한 것, 또는 등 버퍼링 및 / 또는 VM 메모리 모델에 의해 방지 출력을 인터리브되도록 동기화에 대한 언급을하지 않습니다?
편집하다:
예를 들어, 각 스레드에 다음이 포함 된 경우 :
System.out.println("ABC");
보장되는 출력은 다음과 같습니다.
ABC
ABC
또는 다음과 같을 수 있습니다.
AABC
BC
API 문서는 System.out
객체 에 대한 스레드 안전성에 대해 언급 하지 않으며 PrintStream#println(String)
메소드 도 스레드로부터 안전 하다고 가정 할 수 없습니다 .
그러나, 특정 JVM의 기본이되는 구현을위한 스레드 안전 기능을 사용하는 것이 완전히 가능하다 println
(예를 들어, 방법 printf
의 glibc에 ) 때문에, 현실에서, 출력이 (첫 번째 예에 따라 항상 보장됩니다 ABC\n
다음 ABC\n
, 산재 결코 문자를 두 번째 예에 따라). 그러나 많은 JVM 구현이 있으며 JVM 사양을 준수하는 데만 필요하며 해당 사양을 벗어난 규칙은 없습니다.
당신이 경우 반드시 확인해야합니다 당신은 예를 들어, 사용자가 수동으로 상호 배제를 시행해야한다 다음 설명으로 더에 println 호출이 산재 없다는 것을 :
public void safePrintln(String s) {
synchronized (System.out) {
System.out.println(s);
}
}
물론이 예는 단지 설명 일 뿐이며 "해결책"으로 간주해서는 안됩니다. 고려해야 할 다른 많은 요소가 있습니다. 예를 들어 safePrintln(...)
위 의 메서드는 모든 코드가 해당 메서드를 사용하고 아무것도 System.out.println(...)
직접 호출하지 않는 경우에만 안전합니다 .
OpenJDK 소스 코드는 귀하의 질문에 답합니다.
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
OutputStream
비아를 변경하지 않는 한 System.setOut
스레드로부터 안전합니다.
이 스레드 안전이 비록 당신은 많은 스레드를 작성 할 수 있습니다 System.out
그러한를
Thread-1
System.out.println("A");
System.out.println("B");
System.out.println("C");
Thread-2
System.out.println("1");
System.out.println("2");
System.out.println("3");
읽을 수있다
1
2
A
3
B
C
다른 조합 중에서.
따라서 귀하의 질문에 답하려면 :
When you write to System.out
– it acquires a lock on the OutputStream
instance - it will then write to the buffer and immediately flush.
Once it releases the lock, the OutputStream
is flushed and written to. There would not be an instance where you would have different strings joined like 1A 2B
.
Edit to answer your edit:
That would not happen with System.out.println
. Since the PrintStream
synchronizes the entire function, it will fill the buffer and then flush it atomically. Any new thread coming in will now have a fresh buffer to work with.
Just to clarify, say you have two threads, one that prints "ABC"
and another that prints "DEF"
. You will never get output like this: ADBECF
, but you could get either
ABC
DEF
or
DEF
ABC
'Program Tip' 카테고리의 다른 글
If-less 프로그래밍 (기본적으로 조건부 없음) (0) | 2020.11.18 |
---|---|
다중 Moq It.Is (0) | 2020.11.18 |
CQRS 이벤트 소싱 : UserName 고유성 확인 (0) | 2020.11.18 |
Bash : 첫 번째 명령 줄 인수를 취하고 나머지는 전달 (0) | 2020.11.18 |
Visual Studio 2013에서 SSRS (.rptproj) 파일을 열려면 어떻게하나요? (0) | 2020.11.18 |