是否可能在执行调用旁边的语句后打印方法调用输出?

时间:2012-12-08 11:19:20

标签: java multithreading

在下面的代码中可能是预测的输出?

public class Threads2 implements Runnable {
    public void run() 
    {
        System.out.println("run.");
        throw new RuntimeException("Problem");
    }

    public static void main(String[] args) 
    {
        Thread t = new Thread(new Threads2());
        t.start();
        System.out.println("End of method.");
    }
}

作为答案给出的可能结果是:

End of method.
run.
java.lang.RuntimeException: Problem 

OR

run.
java.lang.RuntimeException: Problem 
End of method.

根据我的说法,只有第二个回答是可能的,请帮助我理解。

5 个答案:

答案 0 :(得分:3)

两个答案都是可能的。由线程调度程序决定何时执行并发线程的指令。启动的线程和主线程“并行”运行,唯一的保证是每个线程的指令按顺序执行。但是在两个操作序列之间可能存在任何交错。

您还可以拥有以下内容,BTW。

run
end of method
java.lang.RuntimeException: Problem 

举一个类比,想象一下你有一个跨栏比赛,你告诉每个跑步者一次一个地开始比赛。你知道哪个跑步者会在第一个位置遇到每个障碍吗?不,你没有。这取决于每个跑步者的速度。如果第一个跑步者的速度很慢,那么最后一个跑步者可能会在他面前的第一个障碍中出现。线程也是如此。调度程序按照他想要的任何顺序将每个正在运行的线程分配给核心,并且在任何时候决定。唯一的保证是每个线程都会被执行一段时间。

答案 1 :(得分:2)

t.start();告诉系统启动线程 - 没有任何东西说系统必须立即给出线程执行时间。

另一种可能性是:

run.
End of method.
java.lang.RuntimeException: Problem 

答案 2 :(得分:1)

执行将导致两个线程,主线程(运行main方法的线程)和main方法中创建的线程。由于您无法保证线程运行的顺序,因此代码可以运行多个订单。

所以让我们调用主线程Thread1和创建的线程Thread2。然后,在Thread2启动之后,可能性就是:

  1. Thread1首先获得处理器时间。 ("方法结束......"先打印)
  2. Thread2首先获得处理器时间。 ("运行"先打印)
  3. 并且,实际上有第三种可能性(我认为):

    1. Thread2获取处理器时间并打印"运行"。
    2. Thread2中断,Thread1接管。
    3. Thread1打印"结束..."
    4. Thread2抛出异常。

答案 3 :(得分:0)

首先,请注意,当您写入Exception时,stderr的堆栈跟踪通常会打印到流程的stdout流。通常stderr被重定向到stdout,但这不是必需的。

要考虑的另一件事是文档没有说明PrintStream#println()的并发访问的任何内容,所以当两个线程同时尝试打印时的输出是真的不可预测的。

鉴于在游戏中拥有异常堆栈跟踪没有多大意义(因为它完全是另一个流),问题将减少到主线程和另一个首先写入之间的问题。这不仅取决于JVM调度程序,而且还考虑到该方法不同步,因此它甚至可以打印交错字符串(好吧,我认为这不会发生在现实中,但这就是可能发生。)

答案 4 :(得分:0)

我认为你的问题是“为什么在打印例外后可以打印'run'的输出”。它们位于同一个线程中,应该按顺序执行,这应该保证System.out.print("run");先执行,然后执行throw new RuntimeException("Problem");

这里的问题是那两行代码使用不同的打印队列。 System.out.print()使用标准输出,而由throw new RuntimeException("Problem");引起的错误消息将转到标准错误输出。因此,首先打印哪条消息不仅取决于首先执行哪行代码,还取决于首先刷新到屏幕的输出队列。

如果第二行代码为System.out.print("problem");,则“问题”将始终在“运行”后打印,因为它们使用相同的输出队列