Вывести вывод и сообщение об ошибке на консоль - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь распечатать вывод и сообщение об ошибке на консоль. но иногда последовательность выходных данных изменяется, сначала печатается сообщение об ошибке, а затем печатается простое сообщение. Может ли кто-нибудь помочь мне понять, почему это происходит именно так? последовательность вывода изменяется большую часть времени. В печатной продукции нет согласованности. Я использую Eclipse IDE и получаю следующий вывод.

Я попытался напечатать следующий код,

System.out.println("simple message");  
System.err.println("error message");  

ожидаемый результат таков:

простое сообщение

сообщение об ошибке

но фактический результат таков:

сообщение об ошибке

простое сообщение

Ответы [ 7 ]

0 голосов
/ 14 февраля 2019

как сказал Симеон Икудабо, задача невозможна !! но для самых близких попробуйте это

static void print(PrintStream p, Object o) throws InterruptedException {
    Object lock = new Object();
    synchronized (lock) {

        Runnable r = new Runnable() {
            public void run() {
                synchronized (lock)
                {
                p.println(o);
                lock.notify();
                }
            }
        };
        new Thread(r).start();

        lock.wait();
    }

}

public static void main(String[] args) throws InterruptedException {

    for (int i = 0; i < 50; i++) {
        print(System.out, "out");
        print(System.err, "err");

    }}

Вы можете считать это идеальным, но все же это крошечный маленький шанс выйти из гонки, и это тоже не дается.

0 голосов
/ 14 февраля 2019

Даже если вы очищаете свои потоки после записи, эти потоки читаются различными потоками в Eclipse, и если записи выполняются почти одновременно, бывает, что поток для чтения stderr выполняется перед потоком для stdout, даже если соответствующая запись в stdout случился первым.

Начиная с Java 1.5 существует класс ProcessBuilder, и с этим его можно было бы решить в Eclipse, перенаправив stderr в stdout во время запуска - но функция Eclipse, показывающая вывод stderr в другом цвете, была бы нарушена этим.

Вы можете добавить свое мнение к https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205

0 голосов
/ 14 февраля 2019
  • Помните, это зависит не только от определенной пользователем последовательности, но и от принимающего приложения.
  • Например, если Eclipse IDE имеет два потока, один для получения потока ошибок и один для получения потока system.out, то эти потоки не находятся под вашим контролем, и, следовательно, вы можете видеть, как последовательность меняется время от времени.
  • Если вы не беспокоитесь о производительности, то можете немного поспать.

System.out.println("Out");

Thread.sleep(50);

System.err.println("error");

0 голосов
/ 12 февраля 2019

Как предлагалось в предыдущих ответах , вы можете установить один и тот же поток как для вывода, так и для потока ошибок, используя System.setErr

System.setErr(System.out);

Переназначает «стандартный» поток вывода ошибок.

Но эта настройка не рекомендуется для реального применения в производственной среде

0 голосов
/ 12 февраля 2019

попробуйте это ..

System.out.println("Out");

 System.out.flush();

 System.err.flush();

 System.err.println(" err ");
0 голосов
/ 08 января 2019

Поскольку это два разных исполняющих потока, они выполняются независимо. Кроме того, они не находятся в другой области видимости блока, поэтому метод close () не вызывается, что также не вызывает flush (). Тогда они на одном уровне. Таким образом, JVM берет на себя инициативу и выполняет эти два потока так, как он хотел.

Поэтому преднамеренный вызов flush () в конце каждого потока поможет вам вернуться на место водителя вашего кода

0 голосов
/ 08 января 2019

System.out.println () и System.err.println () - это разные потоки выполнения. Выходные потоки кэшируются, поэтому вся запись идет в этот буфер памяти. После периода тишины они фактически выписаны. Вот цикл for, который по существу снова показывает вашу ошибку:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.err.println("Err");



}

Чтобы "очистить" потоки, вызывайте .flush () каждый раз через цикл:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.out.flush();
    System.err.println("Err");
    System.err.flush();


}

В этом цикле for сначала выводятся сообщение out и сообщение об ошибке, но при каждом сбросе сначала выводятся ваши сообщения out, а затем сообщения err. На выходе будет что-то вроде:

OutErr
Out
Out
Out
Out
Out

Err
Err
Err
Err
Err

И это потому, что System.out и System.err выполняются в разных потоках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...