Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 方法调用输出是否可能在调用旁边的语句执行后打印?_Java_Multithreading - Fatal编程技术网

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

Java 方法调用输出是否可能在调用旁边的语句执行后打印?,java,multithreading,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 = n

在下面的代码中,预测的输出是什么

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 


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

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

顺便说一句,你也可以有以下内容

run
end of method
java.lang.RuntimeException: Problem 
打个比方,假设你有一个跨栏赛跑,你告诉每个赛跑者开始比赛,一次一个。你知道哪个运动员会在第一个位置的每一个栏位上出现吗?不,你没有。这取决于每个跑步者的速度。如果第一个起跑的人跑得很慢,最后一个跑的人可能会在他前面的第一个跨栏跑过来。线程也是如此。调度器将每个正在运行的线程分配给一个核心,按照他想要的任何顺序,在它决定的任何时间。您唯一能保证的是每个线程都会在某个时间执行。

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

另一种可能性是:

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

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

因此,让我们调用主线程Thread1和创建的线程Thread2。在Thread2启动后,可能的情况如下:

  • Thread1首先获取处理器时间。(“方法结束…”首先打印)
  • Thread2首先获取处理器时间。(“运行”先打印)
  • 实际上还有第三种可能性(我认为):

  • Thread2获取处理器时间并打印“run”
  • Thread2被中断,Thread1接管
  • Thread1打印“结束…”
  • Thread2抛出异常

  • 首先,请注意,
    异常
    的堆栈跟踪通常会打印到进程的
    stderr
    流中,而写入
    stdout
    。通常,
    stderr
    被重定向到
    stdout
    ,但这不是必需的

    另一个要考虑的是文档不涉及任何关于“代码”> PrrStuthSo.PrLtLn.()/Cuth>的并发访问,因此当两个线程同时打印时的输出是真正可预测的。

    假设在游戏中有异常堆栈跟踪没有多大意义(因为它是另一个流),那么问题就归结为主线程和另一个线程之间先写哪个。这不仅取决于JVM调度器,而且还考虑到该方法不同步,因此它甚至可以打印交错的字符串(好,我认为这不会在现实中发生,但这是可能发生的)。它们在同一个线程中,应该按顺序执行,这应该保证
    System.out.print(“run”)先执行,然后
    抛出新的运行时异常(“问题”)在此之后执行

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


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

    您认为为什么两种结果都不可能?从技术上讲,所有组合都是可能的。你正在创造一个经典的“竞赛条件”run'与main方法并行执行,这就是为什么可以执行任何命令。但是:由于主线程结束,线程也随之终止,这就是为什么“Run”和“Problem”可能根本不会被打印出来的原因。@Ataylor它不是守护进程线程,因此在没有
    System.exit
    的情况下,程序将在两个线程完成后一段时间退出。(混合
    System.out
    System.err
    也会导致问题。)@Anders R.Bystrup,感谢您的回复和建议
    run.
    End of method.
    java.lang.RuntimeException: Problem