导致运行时异常与控制台输出中的println正确排序 [英] Cause runtime exceptions to be properly ordered with println in console output

查看:155
本文介绍了导致运行时异常与控制台输出中的println正确排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

VM Java控制台输出的一个常见问题是,System.out和System.err通常不会正常进行同步,这可能是因为它们位于不同的线程上。这导致混合输出如下:

A common problem with VM Java console output is that System.out and System.err are not usually synchronized properly, possibly because they are on different threads. This results in mixed up output such as the following:

调试输出与运行时异常堆栈跟踪混合

[8, 1, 3, 5, 9, 13, 15, 17, 19]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
scanning xAnswer: 1 xValue: 1 total: 1 [1, 1, 0, 0, 0, 0, 0, 0, 0]
    at cra.common.Group_jsc.listSubsetSum(Group_jsc.java:29)
scanning xAnswer: 2 xValue: 2 total: 4 [2, 1, 2, 0, 0, 0, 0, 0, 0]
    at cra.common.Group_jsc.main(Group_jsc.java:12)
scanning xAnswer: 3 xValue: 3 total: 9 [3, 1, 2, 3, 0, 0, 0, 0, 0]
scanning xAnswer: 4 xValue: 4 total: 18 [4, 1, 2, 3, 4, 0, 0, 0, 0]
scanning xAnswer: 5 xValue: 5 total: 31 [5, 1, 2, 3, 4, 5, 0, 0, 0]
  reset to xAnswer: 4 xValue: 5 total: 26 [4, 1, 2, 3, 5, 5, 0, 0, 0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
scanning xAnswer: 5 xValue: 6 total: 41 [5, 1, 2, 3, 5, 6, 0, 0, 0]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  reset to xAnswer: 4 xValue: 6 total: 35 [4, 1, 2, 3, 6, 6, 0, 0, 0]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
scanning xAnswer: 5 xValue: 7 total: 52 [5, 1, 2, 3, 6, 7, 0, 0, 0]
  reset to xAnswer: 4 xValue: 7 total: 45 [4, 1, 2, 3, 7, 7, 0, 0, 0]
scanning xAnswer: 5 xValue: 8 total: 64 [5, 1, 2, 3, 7, 8, 0, 0, 0]
  reset to xAnswer: 4 xValue: 8 total: 56 [4, 1, 2, 3, 8, 8, 0, 0, 0]

Process finished with exit code 1

由于在进程结束时发生异常,期望程序中所有println的之后异常的打印。为什么会发生这种情况,可以做些什么来纠正这个问题?

Since the exception occurred at the end of the process I would expect the print out of the exception to occur AFTER all the println's in the program. Why is this happening and what can be done to correct the problem?

(请注意,这个特殊的例子来自IntelliJ的IDEA控制台,但在Eclipse和其他Java IDE)

(note that this particular example is from IntelliJ's IDEA console, but the same thing happens in Eclipse and other Java IDEs)

推荐答案


VM Java控制台输出的一个常见问题是System.out和System .err通常不能正常同步,

A common problem with VM Java console output is that System.out and System.err are not usually synchronized properly,

不,它们是完美同步的。问题是,是混合的,因为它们作为单独调用打印到 println(...)。这是代码从 Exception.printStackTrace()

No, they are synchronized perfectly. The problem is that the lines are intermixed because they are printed as separate calls to println(...). This is the code from Exception.printStackTrace():

        StackTraceElement[] trace = getOurStackTrace();
        for (int i=0; i < trace.length; i++)
            s.println("\tat " + trace[i]);

记录器(如log4j)获取完整的堆栈跟踪,并将多行转换为单个日志输出调用

Loggers (like log4j) get the full stack trace and turn multiple lines into a single log output call which is then persisted atomically.


为什么会发生这种情况,可以做些什么来纠正这个问题?

Why is this happening and what can be done to correct the problem?

通常使用Unix程序时,标准输出是缓冲的,而标准错误不是。我不认为Java是真的,但也许是这样。要读取 System.out 的javadocs:

Typically with Unix programs, standard-out is buffered while standard-error is not. I didn't think that this was true with Java but maybe it is. To read the javadocs of System.out:


标准输出流。这个流已经是

The "standard" output stream. This stream is already

对于 System.err


按照惯例,此输出流用于显示错误消息
或应立即注意的其他信息
即使主要输出流,
变量 out 的值已被重定向到通常不是连续的文件或其他
目的地监视。

By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.

有关详细信息,请参阅此答案:为什么有时会首先打印System.err语句?

See this answer for more details: Why do System.err statements get printed first sometimes?

如果从命令行运行,则应将out和err输出重定向到不同的文件。以下是使用〜unix的方法:

If this running the from the command line, you should redirect the out and err output to different files. Here's how to do that using ~unix:


如何将stderr和stdout重定向到同一行bash中的不同文件?

在Java中,您可以使用 System.setOut(...) code> System.setErr(...)将不同的输出发送到不同的 PrintStream ,这样行不会交错。

In Java you can use System.setOut(...) and System.setErr(...) to send the different output to different PrintStreams so the lines don't interleave.

您编辑的问题要注意,这是从IDE内部发生的。如果您需要使用 System.out err ,那么您可以使用上面的Java代码重定向它们。

You edited the question to note that this is happening from inside an IDE. If you need to use System.out and err then you can redirect them using Java code above.

但是,通常使用日志代码。常见的日志记录包是 log4j logback ,它将单行多行日志消息原子地写入输出文件,这样它们就不会被交错。正如@fge所说,还有 java.util.logging 内置到JVM ,尽管其他包提供更多功能。

However, it is typical to use logging code instead. Common logging packages are log4j or logback which writes a single multi-line log message atomically to the output file so they don't get interleaved. As @fge mentions, there is also java.util.logging built into the JVM although the other packages provide more features.

这篇关于导致运行时异常与控制台输出中的println正确排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆