ようやくJavaで実行されない可能性がある条件はありますか?ありがとう。
注:試行中にJVMが終了した場合 キャッチコードが実行されている finallyブロックは実行できません。 同様に、スレッドを実行している場合 コードが中断または中断される 殺された、最終的なブロックはそうではないかもしれない アプリケーションとしても実行 全体が続きます。
finallyブロックが実行されない他の方法はわかりません...
System.exit仮想マシンをシャットダウンします。
現在実行中のJavaを終了します 仮想マシン議論は役立つ ステータスコードとして。慣例により、 ゼロ以外のステータスコードは異常を示します 終了。
このメソッドは
exit
メソッドの クラスRuntime
。この方法はありません 正常に戻ります。
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
"bye"は上記のコードでは出力されません。
他の人が言ったことをさらに拡大するために、JVMの終了のような何かを引き起こさないものは、最後のブロックを招くでしょう。だから次の方法:
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
奇妙なことに、コンパイルも1も返します。
System.exitに関連して、finallyブロックが実行されない場合がある特定の種類の壊滅的な障害もあります。 JVMのメモリが完全になくなった場合、キャッチせずに、または最終的には発生せずに終了する可能性があります。
具体的には、私たちが愚かに使用しようとしたプロジェクトを思い出します
catch (OutOfMemoryError oome) {
// do stuff
}
JVMにcatchブロックを実行するためのメモリが残っていないため、これは機能しませんでした。
try { for (;;); } finally { System.err.println("?"); }
その場合、finallyは実行されません(非推奨の場合を除く)Thread.stop
と呼ばれる、またはそれと同等のものです。
throw
、 そうしてfinally
ブロックは期待どおりに実行されます。try { throw new ThreadDeath(); } finally { System.err.println("?"); }
- Tom Hawtin - tackline
このスレッドでは、Sunのチュートリアルが誤って引用されています。
注意:tryまたはcatchコードの実行中にJVMが終了すると、finallyブロックは終了します。意志実行しません。同様に、tryまたはcatchコードを実行しているスレッドが中断または強制終了された場合、finallyブロックは意志アプリケーション全体が継続しても実行されません。
finallyブロックについてSunのチュートリアルを詳しく見てみると、「実行されません」とは表示されませんが、「実行されない場合があります」 これが正しい説明です
注意:tryまたはcatchコードの実行中にJVMが終了すると、finallyブロックは終了します。よろしく実行しません。同様に、tryまたはcatchコードを実行しているスレッドが中断または強制終了された場合、finallyブロックはよろしくアプリケーション全体が継続しても実行されません。
この振る舞いの明白な理由は、system.exit()への呼び出しがランタイムシステムスレッドで処理され、jvmをシャットダウンするのに時間がかかるかもしれませんが、その間スレッドスケジューラは最終的に実行を要求することができます。したがって、finallyは常に実行するように設計されていますが、jvmをシャットダウンしている場合は、jvmが最後に実行される前にシャットダウンすることがあります。
また、内部でデッドロック/ライブロックが発生した場合try
ブロック。
これを示すコードは次のとおりです。
public class DeadLocker {
private static class SampleRunnable implements Runnable {
private String threadId;
private Object lock1;
private Object lock2;
public SampleRunnable(String threadId, Object lock1, Object lock2) {
super();
this.threadId = threadId;
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
synchronized (lock1) {
System.out.println(threadId + " inside lock1");
Thread.sleep(1000);
synchronized (lock2) {
System.out.println(threadId + " inside lock2");
}
}
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
}
public static void main(String[] args) throws Exception {
Object ob1 = new Object();
Object ob2 = new Object();
Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
t1.start();
t2.start();
}
}
このコードは以下の出力を生成します。
t1 inside lock1
t2 inside lock1
そして「ようやく」印刷されることはない
これがfinallyブロックを回避できるいくつかの条件です。
最後の非デーモンスレッドは例を終了します。
public class TestDaemon {
private static Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
出力:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
playフレームワークに関連したfinallyブロックが実行されないという非常に特殊なケースに出会いました。
このコントローラアクションコードのfinallyブロックが例外の後にのみ呼び出され、呼び出しが実際に成功したときには呼び出されないことに驚きました。
try {
InputStream is = getInputStreamMethod();
renderBinary(is, "out.zip");
catch (Exception e) {
e.printStackTrace();
} finally {
cleanUp();
}
おそらくスレッドが終了するか、renderBinary()が呼び出されたときに何かが発生しています。私は他のrender()呼び出しについても同じことが起こるのではないかと思いますが、検証はしませんでした。
try / catchの後にrenderBinary()を移動することで問題を解決しました。さらに調査したところ、playにはコントローラアクションの実行後に実行されるメソッドを作成するための@Finallyアノテーションがあることが明らかになりました。ここでの注意点は、これがコントローラ内のANYアクションの実行後に呼び出されることであるため、常に良い選択とは限りません。
以下の場合、最後にブロックは実行されません。
System.exit(0)
から呼び出されるtry
ブロック。try
ブロック他のフリンジケースもあるかもしれません、そこでは最終的にブロックは実行されません。
最後にブロックコードの実行を停止する方法は2つあります。
1. System.exit()を使用してください。
どういうわけか実行制御がtryブロックに達していない場合。
見る:
public class Main
{
public static void main (String[]args)
{
if(true){
System.out.println("will exceute");
}else{
try{
System.out.println("result = "+5/0);
}catch(ArithmeticException e){
System.out.println("will not exceute");
}finally{
System.out.println("will not exceute");
}
}
}
}
//If ArithmeticException Occur Inner finally would not be executed
class Temp
{
public static void main(String[] s)
{
try
{
int x = 10/s.length;
System.out.println(x);
try
{
int z[] = new int[s.length];
z[10] = 1000;
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println(e);
}
finally
{
System.out.println("Inner finally");
}
}
catch(ArithmeticException e)
{
System.out.println(e);
}
finally
{
System.out.println("Outer Finally");
}
System.out.println("Remaining Code");
}
}