Is multi-thread output from System.out.println interleaved
Многопоточный вывод из System.out.println с чередованием
Если несколько потоков вызывают System.out.println(String) без синхронизации, может ли чередоваться вывод? Или запись каждой строки выполняется атомарно? В API не упоминается синхронизация, поэтому это кажется возможным, или чередующийся вывод предотвращается буферизацией и / или моделью памяти виртуальной машины и т.д.?
Однако вполне возможно, что базовая реализация конкретной JVM использует потокобезопасную функцию для println метода (например, printf на glibc), так что на самом деле вывод будет гарантирован для вашего первого примера (всегда ABC\n тогда ABC\n, никогда не чередующиеся символы для вашего второго примера). Но имейте в виду, что существует множество реализаций JVM, и от них требуется только соблюдение спецификации JVM, а не каких-либо соглашений за пределами этой спецификации.
Если вы абсолютно должны гарантировать, что никакие вызовы println не будут чередоваться, как вы описываете, тогда вы должны принудительно выполнить взаимное исключение вручную, например:
Конечно, этот пример является лишь иллюстрацией и его не следует воспринимать как "решение"; необходимо учитывать множество других факторов. Например, safePrintln(...) приведенный выше метод безопасен только в том случае, если весь код использует этот метод и ничто не вызывает System.out.println(...) напрямую.
Когда вы записываете в System.out – он получает блокировку для OutputStream экземпляра - затем он записывает в буфер и немедленно сбрасывает.
Как только он снимает блокировку, OutputStream очищается и записывается в. Не было бы случая, когда у вас были бы разные строки, соединенные подобным образом 1A 2B.
Отредактируйте, чтобы ответить на вашу правку:
Этого не произошло бы с System.out.println. Поскольку PrintStream синхронизирует всю функцию, она заполнит буфер, а затем очистит его атомарно. Любой новый входящий поток теперь будет иметь новый буфер для работы.
Ответ 4
Просто для пояснения, предположим, у вас есть два потока, один, который печатает "ABC", а другой, который печатает "DEF". Вы никогда не получите такой вывод: ADBECF, но вы могли бы получить либо