마침내 자바에서 실행되지 않는 조건이 있습니까? 감사.
답변
로부터 일 자습서
참고 : try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록이 실행되지 않을 수 있습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 중단되거나 종료되면 응용 프로그램 전체가 계속 되더라도 finally 블록이 실행되지 않을 수 있습니다.
나는 finally 블록이 실행되지 않는 다른 방법을 모릅니다.
답변
System.exit 는 가상 머신을 종료합니다.
현재 실행중인 Java Virtual Machine을 종료합니다. 인수는 상태 코드 역할을합니다. 일반적으로 0이 아닌 상태 코드는 비정상 종료를 나타냅니다.
이 메서드는
exit
클래스 의 메서드를 호출합니다Runtime
. 이 메서드는 정상적으로 반환되지 않습니다.
try {
System.out.println("hello");
System.exit(0);
}
finally {
System.out.println("bye");
} // try-finally
“bye”는 위의 코드에서 인쇄되지 않습니다.
답변
다른 사람들의 말을 확장하기 위해 JVM 종료와 같은 것을 유발하지 않는 것은 finally 블록을 발생시킵니다. 따라서 다음 방법 :
public static int Stupid() {
try {
return 0;
}
finally {
return 1;
}
}
이상하게도 컴파일하고 1을 반환합니다.
답변
System.exit와 관련하여 finally 블록이 실행되지 않는 특정 유형의 치명적인 오류도 있습니다. JVM에 메모리가 완전히 부족하면 catch 또는 최종적으로 발생하지 않고 종료 될 수 있습니다.
특히 우리가 어리석게 사용하려고 한 프로젝트가 기억납니다.
catch (OutOfMemoryError oome) {
// do stuff
}
JVM에는 catch 블록을 실행하기위한 메모리가 남아 있지 않기 때문에 작동하지 않았습니다.
답변
try { for (;;); } finally { System.err.println("?"); }
이 경우 finally는 실행되지 않습니다 (비추천 항목 Thread.stop
이 호출되거나 도구 인터페이스를 통해 이와 동등한 항목이 호출 되지 않는 한 ).
답변
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
“마지막으로”는 인쇄되지 않습니다.