#java #thread-sleep #system.out
#java #поток-спящий режим #system.out
Вопрос:
Я знал, что System.out буферизован. Он не будет выводить выходные данные на терминал, пока они не будут явно сброшены или программа не будет завершена.
Я написал ниже программу, чтобы проверить свое понимание. Я думал, что вывод моей программы будет напечатан, когда программа завершится, потому что я явно не сбрасываю поток. Но вывод печатается, как только выполняется печать, а затем программа переходит в 5-секундный режим ожидания.
Не мог бы кто-нибудь, пожалуйста, указать причину.
class PrintandSleep {
public static void main(String args[]) throws InterruptedException{
System.out.print("xyz");
Thread.sleep(5000);
}
}
Комментарии:
1. Вы, конечно, хотите поменять местами две строки?
2. Я действительно смущен тем, как это может сбить с толку. Вы указываете программе печатать, а затем переходите в режим сна. Я не понимаю, почему вы ожидаете, что это будет по-другому. Если вы не привыкли читать снизу вверх?
3. @user3580294 Поскольку System.out должен быть буферизован в строке, OP также предполагает, что System.out.print() ничего не печатает (поскольку нигде нет новой строки), по крайней мере, до тех пор, пока поток не будет закрыт при выходе из программы.
4. @nos Ах, это имеет смысл. Не нажимал, пока вы не сказали это.
5. @user3580294 Я ожидал, что буфер будет сброшен, и вывод появится при завершении программы, потому что System.out — это буферизованный поток.
Ответ №1:
Причина в том, что запись создается с флагом автоматической очистки, установленным в true.
public PrintStream(OutputStream out, boolean autoFlush, String encoding)
В таком случае write(String)
, когда мы вызываем flush()
, мы также вызываем.
Код из версии 8:
java.io.PrintStream
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush amp;amp; (s.indexOf('n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
Посмотрите в код, когда вы не можете определить, что происходит.
Комментарии:
1. Интересно, что, по крайней мере, при быстром обращении к отладчику
autoFlush
флаг в данном случае фактически не имеет значения, поскольку (по крайней мере, на моем компьютере) вывод записывается на консоль до того, как флажок установлен. Не слишком уверен, что происходит.2. Здесь мы вызываем
print(String)
, а неwrite(String)
. В документации ничего не говорится оautoFlush
наличии эффекта.3.Кроме того, интересно то, что оба
System.err
иSystem.out
создаются сautoFlush=true
помощью (см. hg.openjdk.java.net/jdk7/jdk7/jdk/file/cf44386c8fe3/src/share /…) — разве это не означает, что выходы в System.err и System.out всегда должны быть синхронизированы (что, как мы знаем, не так)?4. @Joni, печать общедоступна, запись закрыта. Вызывая print, вы вызываете write .
5. @Andreas Эр, переписать. Мне любопытно, какое различие между различными потоками вывода / записывающими устройствами тогда и когда будет иметь значение очистка одного или другого. Из моей проверки javadoc
text/charOut.flushBuffer()
просто сбросил некоторые буферы, не сбросив базовый поток байтов, поэтому мне немного любопытно, что происходит…