1. ホーム
  2. java

System.out.printlnからのマルチスレッド出力はインターリーブされているか

2023-09-12 04:59:39

質問

複数のスレッドが同期を取らずに System.out.println(String) を呼び出した場合、出力はインターリーブされるのでしょうか?それとも、各行の書き込みはアトミックなのでしょうか?その場合 API は同期について言及しないので、これは可能なように思われる、またはインターリーブ出力はバッファリングおよび/またはVMメモリモデルなどによって防止されていますか?

EDIT。

例えば、各スレッドに

System.out.println("ABC");

は出力が保証されています。

ABC
ABC

とかありそう。

AABC
BC

どのように解決するのですか?

API ドキュメントでは、スレッドセーフについて言及されていないため System.out オブジェクトの もまた PrintStream#println(String) メソッド スレッドセーフであると仮定することはできません .

しかしながら、特定のJVMの基礎となる実装が、スレッドセーフな関数を println メソッドにスレッドセーフな関数を使用している可能性は十分にあります (例: printf glibc上 ) で、実際には、最初の例のように出力が保証されます (常に ABC\n であれば ABC\n となり、2つ目の例のように文字が挟まることはありません)。 しかし、多くのJVM実装があり、それらはJVM仕様に準拠することだけが要求され、その仕様の外側のいかなる規約にも従わないことを心に留めておいてください。

もしあなたが を絶対に保証しなければならない場合 を絶対に保証しなければならない場合、例えば、手動で相互排除を強制する必要があります。

public void safePrintln(String s) {
  synchronized (System.out) {
    System.out.println(s);
  }
}

もちろん、この例はあくまで例示であり、解決策とみなすべきではありません。例えば safePrintln(...) メソッドが安全であるのは すべて のコードがそのメソッドを使用し、何も System.out.println(...) を直接呼び出すことはありません。