почему System.out.prinln не работает?

Время от времени я хочу использовать System.out.prinln для отладки вещей вместо использования отладчика, или я хочу, чтобы простая программа записывала в стандартный вывод, чтобы я мог что-то регистрировать, не тратя время на правильную настройку ведения журнала. Я заметил, что иногда мой текст печатается не по порядку. Например.:

System.out.println("A");
System.out.println("B");    
System.out.println("C");

может привести к

A
C
B

печатается.

Я почти уверен, что я не сумасшедший, поэтому у меня есть два вопроса:

  1. Почему это происходит?
  2. Какой простой способ предотвратить это?

РЕДАКТИРОВАТЬ: Дополнительная информация:

Я запускаю модульные тесты, которые создают запросы Lucene с помощью JUnit. Чтобы распечатать их, я написал этот класс:

public class LogHelper { //TODO-DAVID remove
    public static final boolean ENABLED = true;
    public static final boolean DISABLED = false;

    private boolean enabled;

    public LogHelper(boolean enabled){
        this.enabled = enabled;
    }

    public synchronized void debug(String someString){
        if(enabled){
            System.out.println(someString);
        }
    }
}

Я попытался синхронизировать 'debug()' на случай, если несколько потоков вызывали его, но странная печать все еще иногда происходит не по порядку.


person David    schedule 19.10.2013    source источник
comment
Я не хочу звучать как заезженная пластинка, но мы почти не сможем пролить свет на это без SSCCE.   -  person Dennis Meng    schedule 19.10.2013
comment
Если некоторые из них на самом деле являются System.err.println, вы получите некоторое чередование на консоли, потому что System.out буферизуется, но System.err всегда сбрасывается.   -  person rob    schedule 19.10.2013
comment
Если вы не покажете нам реальный конкретный (полный) пример, мы не сможем объяснить, что происходит. Существует ряд возможных объяснений.   -  person Stephen C    schedule 19.10.2013
comment
+1 за то, что ты не сумасшедший :)   -  person Konstantin Yovkov    schedule 19.10.2013
comment
@DennisMeng и @_Stephen C, как я уже сказал в своем посте: это происходит нечасто и в нескольких простых программах. Поскольку это происходит только иногда, даже в одной и той же программе, я не могу дать вам SSCCE. Я полагаю, что мог бы написать цикл for, который выводит что-то, запускает его до тех пор, пока (в какой-то неопределенный момент в будущем) он, наконец, не выведет что-то не по порядку, а затем загрузит его. Но это пустая трата нашего времени.   -  person David    schedule 19.10.2013
comment
@DennisMeng и @_Stephen C, я добавил немного больше информации. Это не совсем SSCCE, скорее S_CCE, но это то, на что у меня сейчас есть время.   -  person David    schedule 19.10.2013
comment
@Коко, спасибо. Я покажу это здешнему персоналу. Трудно набрать смирительную рубашку. Было бы неплохо, если бы я мог его снять.   -  person David    schedule 19.10.2013
comment
Наконец, @StephenC, вы просто имеете в виду, что существует бесконечное количество теоретически возможных объяснений, или на ум приходят конкретные? Если последнее, можете ли вы их предложить?   -  person David    schedule 19.10.2013
comment
@David - Нет, я не имею в виду, что существует бесконечное количество теоретически возможных объяснений. Не будь смешным! Учитывая то, что вы добавили, есть только одно вероятное объяснение; см. принятый ответ.   -  person Stephen C    schedule 19.10.2013


Ответы (2)


Этого никогда не произойдет, если печать не происходит в разных потоках. Тогда порядок выполнения может быть неопределенным. Если, с другой стороны, вы пишете в System.out и System.err и видите беспорядочный вывод, это потому, что это два разных потока, которые по умолчанию записывают в один и тот же вывод, и один или другой может выйти первым, особенно из-за буферизации или других соображений.

person Ryan Stewart    schedule 19.10.2013
comment
спасибо за Ваш ответ. Я обновил свой вопрос выше, чтобы указать, что я синхронизировал свой вызов system.out.println(), но все еще вижу странное поведение. Есть идеи по этому поводу? - person David; 19.10.2013
comment
synchronized в вашем примере никоим образом не помешает нескольким потокам печатать вещи не по порядку, если это действительно то, что происходит. Это просто означает, что только один поток может печатать одновременно. Мой ответ в силе. - person Ryan Stewart; 19.10.2013
comment
Ах. Да, теперь это имеет смысл. И похоже, что Junit выполняет тесты одновременно: stackoverflow.com/questions/7267790/ Ответ принят. - person David; 19.10.2013

Я уверен, что никогда не произойдет с вашим примером в одном потоке.

В любом случае, убедитесь, что у вас нет вызовов функций внутри System.out.println(, которые могут создать новый поток.. особенно функции, которые вызывают OS System.. они обычно путаются...

person Jose Almeida    schedule 19.10.2013