2

以下のコードでは、予測される出力は何でしょうか?

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.
java.lang.RuntimeException: Problem 
End of method.

私によると、2番目の答えしかできません。理解するのを手伝ってください。

4

5 に答える 5

3

どちらの答えも可能です。並行スレッドの命令をいつ実行するかを決定するのは、スレッド スケジューラ次第です。開始されたスレッドとメインスレッドは「並行して」実行され、唯一の保証は各スレッドの命令が順番に実行されることです。ただし、2 つの一連の操作の間にインターリーブが発生する可能性があります。

ところで、次のようにすることもできます。

run
end of method
java.lang.RuntimeException: Problem 

例えると、ハードル レースがあり、各ランナーに 1 人ずつレースを開始するように指示するとします。どのランナーが各ハードルで 1 位になるか知っていますか? いいえ、あなたはしません。それは各ランナーの速度に依存します。最初にスタートした走者が非常に遅い場合、最後の走者が彼の前の最初のハードルに来る可能性があります。それはスレッドも同じです。スケジューラは、実行中の各スレッドを任意の順序で任意の時間にコアに割り当てます。唯一の保証は、各スレッドがしばらく実行されることです。

于 2012-12-08T11:24:21.140 に答える
2

t.start();システムにスレッドを開始するように指示します-システムが実際にスレッドの実行時間をすぐに与えなければならないということは何もありません。

別の可能性は次のとおりです。

run.
End of method.
java.lang.RuntimeException: Problem 
于 2012-12-08T11:25:31.657 に答える
1

実行すると、メイン スレッド (メイン メソッドを実行するスレッド) とメイン メソッドで作成されたスレッドの 2 つのスレッドが生成されます。スレッドが実行される順序に関しては何も保証できないため、コードが実行される順序は複数あります。

それでは、メイン スレッド Thread1 と、作成されたスレッド Thread2 を呼び出しましょう。Thread2 が開始された後の可能性は次のとおりです。

  1. スレッド 1 は最初にプロセッサ時間を取得します。(「メソッドの終わり...」が最初に出力されます)
  2. Thread2 は最初にプロセッサー時間を取得します。(「実行」は最初に印刷されます)

そして、実際には3番目の可能性があります(私は思います):

  1. Thread2 はプロセッサ時間を取得し、「run」を出力します。
  2. Thread2 が中断され、Thread1 が引き継ぎます。
  3. スレッド 1 が「... の終わり」を出力します。
  4. Thread2 が例外をスローします。
于 2012-12-08T11:28:05.443 に答える
0

まず、Exceptionのスタック トレースは通常stderr、プロセスのストリームに出力されることに注意してくださいstdoutstderrにリダイレクトされることがよくありstdoutますが、これは必須ではありません。

考慮すべきもう 1 つのことは、ドキュメントには の同時アクセスについて何も記載されていないPrintStream#println()ため、2 つのスレッドが同時に印刷を試みた場合の出力は本当に予測不可能です。

ゲーム内で例外スタック トレースを使用する意味があまりないことを考えると (これはまったく別のストリームであるため)、問題はメイン スレッドと他のスレッドの間のどちらが最初に書き込むかという問題に軽減されます。これは JVM スケジューラ次第であるだけでなく、メソッドが同期されていないことも考慮して、インターリーブされた文字列を出力することさえできます (まあ、これが実際に起こるとは思いませんが、これは起こる可能性があります) 。 .

于 2012-12-08T11:29:22.470 に答える
0

あなたの質問は、「例外が出力された後に「実行」の出力が出力されるのはなぜですか」だと思います。それらは同じスレッドにあり、順番に実行する必要があります。これによりSystem.out.print("run");、最初に実行され、その後throw new RuntimeException("Problem");に実行されることが保証されます。

ここでの問題は、これら 2 行のコードが異なる印刷キューを使用していることです。System.out.print()標準出力を使用しますが、 によって引き起こされたエラー メッセージthrow new RuntimeException("Problem");は標準エラー出力に送られます。したがって、どのメッセージが最初に出力されるかは、コードのどの行が最初に実行されるかだけでなく、どの出力キューが最初に画面にフラッシュされるかによっても異なります。

コードの 2 行目がSystem.out.print("problem");「問題」の場合、同じ出力キューを使用しているため、常に「実行」後に出力されます。

于 2016-03-08T00:53:51.970 に答える