2012-03-29 2 views
3

Может ли кто-нибудь сказать мне, почему у меня всегда есть этот странный выход после запуска этого цикла? Это проблема с потоками или что?Странный выход при запуске петли

for(int i=0;i<10;i++){ 
    System.out.println("out: "+i); 
    System.err.println("err: "+(i+1)); 
    } 

-> ВЫХОД:

err: 1 
    out: 0 
    err: 2 
    err: 3 
    err: 4 
    out: 1 
    out: 2 
    out: 3 
    out: 4 
    err: 5 
    out: 5 
    err: 6 
    out: 6 
    err: 7 
    err: 8 
    out: 7 

    out: 8 
    err: 9 
    out: 9 
    err: 10 
    out: 10 

ответ

11

Ваш терминал запускает ваше приложение и имеет два файловых дескриптора, подключенных к нему, один для stdout и один для stderr. Затем он должен прочитать данные, которые ваше приложение выводит на эти файловые дескрипторы и выводит на экран. Нет никакой гарантии, как приложение терминала (или ОС, если на то пошло) реализует это взаимодействие. Представьте, что на самом деле терминал имеет 2 потока, которые читаются из stdout и stderr параллельно. Порядок, в котором эти 2 потока будут получать данные из fds и на экран, не будет гарантированно последовательным, когда ваше приложение выйдет.

+0

Это интересно. Первоначально я извинялся, потому что думал, что это неправильно. Это было мое предположение, что Java буферизует 'System.out' и' System.err' не буферизуется. Но если я запустил класс из командной строки, я вижу '' oeoeoeoeoeoeoeoe ''отлично чередующийся. Это означает, что это приложение делает что-то другое. Захватывающий. Спасибо @MK. +1 – Gray

+0

@Gray Я думаю, вы правы, что System.err не буферизуется, но я не думаю, что они взаимоисключающие. Я пытался дать общее представление о том, почему они будут чередовать. Также я думаю, что печать \ n может привести к промывке? В этом случае поведение stdout и stderr будет одинаковым. –

+0

Мой комментарий не был с вами не согласен. Я полностью согласен. По умолчанию PrintStream не скрывается, когда видит «\ n». Я не уверен, как были настроены «System.out» и «System.err». – Gray

3

Стандартный вывод и стандартная ошибка имеют отдельные буферы. Перемеживание является нормальным. Попробуйте flushing поток вывода после каждого вызова печати.

Смежные вопросы