Program Tip

System.out.println의 다중 스레드 출력이 인터리브 됨

programtip 2020. 11. 18. 09:38
반응형

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();
    }
}

참조 : http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/39e8fe7a0af1/src/share/classes/java/io/PrintStream.java


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

참고URL : https://stackoverflow.com/questions/9459657/is-multi-thread-output-from-system-out-println-interleaved

반응형