[java] Java에서 System.exit를 언제 호출해야합니까

Java System.exit(0)에서 다음 코드 와의 차이점은 무엇입니까 ?

public class TestExit
{
    public static void main(String[] args)
    {
        System.out.println("hello world");

        System.exit(0);  // is it necessary? And when it must be called? 
    }
}

문서는 말한다 : “이 방법은 일반적으로 반환하지 않습니다.” 무슨 뜻인가요?



답변

System.exit()프로그램이 종료되기 전에 종료 후크 를 실행하는 데 사용할 수 있습니다 . 이는 프로그램의 모든 부분이 서로를 인식 할 수없고 인식해서는 안되는 더 큰 프로그램에서 종료를 처리하는 편리한 방법입니다. 그런 다음 누군가 종료하려면 간단히 전화를 걸 수 있으며 System.exit()종료 후크 (올바르게 설정된 경우)는 파일 닫기, 리소스 해제 등 필요한 모든 종료 행사를 처리합니다.

“이 방법은 정상적으로 반환되지 않습니다.” 메서드가 반환되지 않음을 의미합니다. 실이 거기에 가면 다시 돌아 오지 않습니다.

프로그램을 종료하는 또 다른 더 일반적인 방법은 단순히 main방법 의 끝에 도달하는 것입니다 . 그러나 데몬 이외의 스레드가 실행중인 경우 종료되지 않으므로 JVM이 종료되지 않습니다. 따라서 데몬 이외의 스레드가있는 경우 데몬 이외의 스레드를 모두 종료하고 다른 자원을 해제하려면 다른 방법 (종료 후크보다)이 필요합니다. 데몬 이외의 다른 스레드가없는 경우에서 복귀 main하면 JVM이 종료되고 종료 후크가 호출됩니다.

어떤 이유로 든 셧다운 훅은 과소 평가되고 오해를 불러 일으키는 메커니즘으로 보이며 사람들은 프로그램을 종료하기 위해 모든 종류의 전용 사용자 지정 해킹으로 휠을 재발 명하고 있습니다. 종료 후크를 사용하는 것이 좋습니다. 어쨌든 사용할 표준 런타임 에는 모두 있습니다 .


답변

이 경우에는 필요하지 않습니다. 추가 스레드가 시작되지 않았으므로 종료 코드 (기본값 0)를 변경하지 않습니다. 기본적으로 의미가 없습니다.

문서에서 메소드가 정상적으로 반환되지 않는다고 말하면 컴파일러가 알지 못하더라도 후속 코드 행에 효과적으로 도달 할 수 없음을 의미합니다 .

System.exit(0);
System.out.println("This line will never be reached");

예외가 발생하거나 리턴하기 전에 VM이 종료됩니다. “반환”하지 않습니다.

System.exit()IME를 호출 할 가치가있는 경우는 매우 드 rare니다 . 명령 행 도구를 작성하는 경우 이치에 맞을 수 있으며 예외를 던지기보다는 종료 코드를 통해 오류를 표시하려고합니다. .


답변

System.exit(0)JVM을 종료합니다. 이와 같은 간단한 예에서는 차이를 인식하기가 어렵습니다. 이 매개 변수는 OS로 다시 전달되며 일반적으로 비정상 종료 (예 : 치명적인 오류)를 나타내는 데 사용되므로 배치 파일 또는 쉘 스크립트에서 java를 호출 한 경우이 값을 가져 와서 아이디어를 얻을 수 있습니다. 응용 프로그램이 성공한 경우.

System.exit(0)응용 프로그램 서버에 배포 된 응용 프로그램 을 호출 한 경우 상당한 영향을 미칩니다 (사용하기 전에 생각하십시오).


답변

이 메소드는 세계의 끝이므로 절대로 리턴하지 않으며 다음 코드는 실행되지 않습니다.

예제에서 응용 프로그램은 코드의 동일한 지점에서 종료되지만 System.exit을 사용하는 경우 종료됩니다. 사용자 정의 코드를 환경에 반환하는 옵션이 있습니다.

System.exit(42);

누가 종료 코드를 사용합니까? 응용 프로그램을 호출 한 스크립트 Windows, Unix 및 기타 모든 스크립트 가능한 환경에서 작동합니다.

왜 코드를 반환합니까? “성공하지 못했습니다”, “데이터베이스가 응답하지 않았습니다”와 같은 것을 말하십시오.

종료 코드를 od 코드로 가져 와서 유닉스 쉘 스크립트 나 Windows cmd 스크립트에서 사용하는 방법을 보려면 이 사이트에서이 답변을 확인 하십시오


답변

복잡한 종료 후크가있는 응용 프로그램에서는 알 수없는 스레드에서이 메서드를 호출하면 안됩니다. System.exitJVM이 종료 될 때까지 호출이 차단되므로 정상적으로 종료되지 않습니다. 마치 마치 실행하기 전에 전원 플러그를 뽑은 코드가 실행중인 것처럼 보입니다. 호출 System.exit하면 프로그램의 종료 후크와 System.exit프로그램 종료까지 호출하는 스레드가 시작 됩니다. 이는 종료 후크가 차례로 System.exit호출 된 스레드에 태스크를 제출 하면 프로그램이 교착 상태가된다는 의미입니다.

내 코드에서 다음을 처리하고 있습니다.

public static void exit(final int status) {
    new Thread("App-exit") {
        @Override
        public void run() {
            System.exit(status);
        }
    }.start();
}


답변

답변이 실제로 도움이되었지만 더 자세한 내용을 놓친 방법이 있습니다. 위의 답변 외에도 아래의 Java 종료 프로세스를 이해하는 데 도움이되기를 바랍니다.

  1. 순차적 * 종료에서 JVM은 먼저 등록 된 모든 종료 후크를 시작합니다. 종료 후크는 Runtime.addShutdownHook에 등록 된 시작되지 않은 스레드입니다.
  2. JVM은 종료 후크가 시작되는 순서를 보장하지 않습니다. 종료시 응용 프로그램 스레드 (데몬 또는 비 데몬)가 여전히 실행중인 경우 종료 프로세스와 동시에 계속 실행됩니다 .
  3. 모든 종료 후크가 완료되면 runFinalizersOnExit가 true 인 경우 JVM이 종료자를 실행하도록 선택한 다음 중지됩니다.
  4. JVM은 종료시 여전히 실행중인 응용 프로그램 스레드를 중지하거나 중단하지 않습니다. JVM이 결국 정지되면 갑자기 종료됩니다.
  5. 종료 후크 또는 종료자가 완료되지 않으면 순서대로 종료 프로세스가 중단되고 JVM을 갑자기 종료해야합니다.
  6. 갑작스런 종료에서 JVM은 JVM을 중지하는 것 외에 다른 작업을 수행 할 필요가 없습니다. 종료 후크가 실행되지 않습니다.

PS : JVM은 순서대로 또는 갑작스럽게 종료 될 수 있습니다 .

  1. 마지막 “정상”(nondaemon) 스레드가 종료되거나 누군가 System.exit를 호출하거나 다른 플랫폼 별 수단 (예 : SIGINT 전송 또는 Ctrl-C 치기)에 의해 순차적으로 종료됩니다.
  2. 위의 방법은 JVM을 종료하는 표준적이고 선호되는 방법이지만 Runtime.halt를 호출하거나 운영 체제를 통해 JVM 프로세스를 종료 (예 : SIGKILL 전송)하여 갑자기 종료 할 수도 있습니다.

답변

System.exit(0)다음과 같은 이유로 전화해서는 안됩니다 .

  1. 숨겨진 “goto”와 “gotos”는 제어 흐름을 깨뜨립니다. 이 맥락에서 후크에 의존하는 것은 팀의 모든 개발자가 알고 있어야하는 정신적 매핑입니다.
  2. 프로그램을 “정상적으로”종료하면 운영 체제에 동일한 종료 코드가 제공 System.exit(0)되므로 중복됩니다.

    프로그램이 “정상적으로”종료되지 않으면 개발에 대한 통제력을 상실한 것입니다 [디자인]. 항상 시스템 상태를 완전히 제어해야합니다.

  3. 정상적으로 중지되지 않은 스레드 실행과 같은 프로그래밍 문제는 숨겨집니다.
  4. 스레드를 비정상적으로 중단하는 응용 프로그램 상태가 일치하지 않을 수 있습니다. (# 3 참조)

그건 그렇고 : 비정상적인 프로그램 종료를 나타내려면 0 이외의 다른 반환 코드를 반환하는 것이 좋습니다.