Programing

시스템을 언제 불러야 할까?자바로 퇴장하다

c10106 2022. 4. 16. 09:05
반응형

시스템을 언제 불러야 할까?자바로 퇴장하다

자바에서, 어떤 차이가 있는가? 없는가?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(non-daemon) 그러나 실행 중인 비 데몬 스레드가 있으면 스레드가 종료되지 않으므로 JVM이 종료되지 않는다.따라서 이러한 비 데몬 스레드가 있다면, 모든 비 데몬 스레드를 종료하고 다른 리소스를 해제하기 위해 (셧다운 후크보다) 다른 수단이 필요하다.다른 데몬이 아닌 스레드가 없는 경우 다음에서 돌아오십시오.mainJVM을 종료하고 종료 후크를 호출할 것이다.

어떤 이유에서인지 셧다운 후크는 저평가되고 오해된 메커니즘인 것 같고, 사람들은 그들의 프로그램을 그만두기 위해 모든 종류의 독점적인 맞춤식 해킹으로 바퀴를 다시 발명하고 있다.나는 셧다운 후크를 사용하는 것을 권장한다; 어쨌든 당신이 사용할 표준 런타임에는 모든 것이 있다.

그런 경우에는 필요 없다.추가 스레드가 시작되지 않을 것이며, 종료 코드(기본값은 0)를 변경하지 않을 것이다. 기본적으로 무의미하다.

문서들이 그 방법이 정상적으로 돌아오지 않는다고 말하는 것은 컴파일러가 다음과 같은 사실을 알지 못하더라도, 후속 코드 라인에 효과적으로 접근할 수 없다는 것을 의미한다.

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

예외가 발생하거나 VM이 종료된 후 반환하십시오.그것은 결코 "그냥 돌아올" 수 없을 것이다.

부를 만한 가치가 있는 것은 매우 드물다.System.exit()IME. 명령줄 도구를 쓰는 것이 타당할 수 있으며, 예외를 그냥 던지기 보다는 종료 코드를 통해 오류를 표시하고자 하는 경우...하지만 마지막으로 정상 생산 코드로 사용한 게 언제인지 기억이 안 나.

그 방법은 세상의 종말이기 때문에 결코 돌아오지 않고 다음에 실행될 당신의 코드는 하나도 없을 것이다.

당신의 예에서, 당신의 어플리케이션은 코드의 같은 지점에서 어쨌든 종료되지만, 만약 당신이 System.exit를 사용한다면.환경에 사용자 지정 코드를 반환할 수 있는 옵션, 예를 들어,

System.exit(42);

누가 너의 퇴장 코드를 사용할 거니?응용 프로그램을 호출한 스크립트.Windows, Unix 및 기타 모든 스크립팅 가능한 환경에서 작동 가능.

왜 코드를 반환하지?"나는 성공하지 못했다"는 등의 말을 하자면, "데이터베이스가 대답하지 않았다"는 것이다.

종료 코드에서 값을 가져와서 Unix 셸 스크립트 또는 윈도우즈 cmd 스크립트에 사용하는 방법을 보려면 이 사이트에서 이 대답을 확인하십시오.

System.exit(0)JVM을 종료한다.이와 같은 간단한 예에서는 그 차이를 이해하기가 어렵다.매개변수는 OS로 다시 전달되며, 보통 비정상적인 종료(예: 치명적인 오류)를 나타내기 위해 사용되므로 배치 파일이나 셸 스크립트에서 자바를 호출하면 이 값을 얻을 수 있고 응용 프로그램이 성공적이었는지 아이디어를 얻을 수 있을 것이다.

네가 전화하면 꽤 영향이 있을 거야.System.exit(0)응용 프로그램 서버에 배포된 응용 프로그램(해 보기 전에 먼저 생각해 보십시오.

복잡한 셧다운 후크가 있을 수 있는 애플리케이션에서, 이 방법은 알 수 없는 스레드로부터 호출되어서는 안 된다.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();
}

다음과 같은 이유로 전화를 해서는 안 된다.

  1. 이것은 숨겨진 "goto"와 "gotos"가 제어 흐름을 끊는 것이다.이러한 맥락에서 후크에 의존하는 것은 팀의 모든 개발자들이 알아야 하는 정신적 지도화다.
  2. 프로그램을 "보통" 종료하면 운영 체제에 동일한 종료 코드가 제공된다.System.exit(0)그래서 그것은 중복된다.

    프로그램이 "일반적으로" 종료할 수 없는 경우, 개발[설계]에 대한 통제력을 상실한 것이다.시스템 상태를 항상 완전히 제어해야 한다.

  3. 일반적으로 중지되지 않는 스레드 실행과 같은 프로그래밍 문제는 숨겨진다.
  4. 스레드를 비정상적으로 중단하는 일관성 없는 애플리케이션 상태가 발생할 수 있음(3번 참조)

그런데: 0이 아닌 다른 반환 코드를 반환하는 것은 비정상적인 프로그램 종료를 나타내려면 이치에 맞는다.

답은 정말 도움이 되었지만, 어떤 사람들은 더 자세한 세부사항을 놓쳤다.위의 답변 외에도 아래 내용이 자바에서 종료 과정을 이해하는 데 도움이 되었으면 한다.

  1. 순서* 종료 시 JVM은 먼저 등록된 모든 종료 후크를 시작한다.종료 후크는 Runtime.addShutdownHook에 등록된 분할되지 않은 스레드입니다.
  2. JVM은 셧다운 후크가 시작되는 순서에 대해 어떤 보증도 하지 않는다.애플리케이션 스레드(데몬 또는 비에몬)가 여전히 종료 시간에 실행 중인 경우, 종료 프로세스와 동시에 계속 실행된다.
  3. 모든 종료 후크가 완료되면, JVM은 FinalizersOnExit 실행이 참인 경우 파이널라이저 실행을 선택한 다음 중지할 수 있다.
  4. JVM은 종료 시에도 여전히 실행 중인 애플리케이션 스레드를 중지하거나 중단하려고 시도하지 않는다. 이러한 스레드는 JVM이 결국 중지될 때 갑자기 종료된다.
  5. 셧다운 후크나 파이널라이저가 완료되지 않으면, 질서정연한 셧다운 프로세스 "정지"와 JVM을 갑자기 종료해야 한다.
  6. 갑작스러운 종료에서는 JVM이 JVM을 정지하는 것 외에 다른 작업을 수행할 필요가 없으며, 종료 후크는 실행되지 않는다.

PS: JVM은 질서정연하거나 갑작스럽게 종료될 수 있다.

  1. 마지막 "정상"(논다에몬) 스레드가 종료될 때 질서 있는 종료가 시작되며, 누군가가 System을 호출한다.종료 또는 다른 플랫폼별 수단(예: SIGINT 전송 또는 Ctrl-C 누르기)을 사용하여 종료한다.
  2. 위가 JVM이 종료되는 표준 방식이고 선호되는 방식이지만, Runtime을 호출하여 JVM을 갑자기 종료할 수도 있다.운영 체제를 통해 JVM 프로세스를 중지하거나 중지(예: SIGKILL 전송)

System.exit 필요

  • 0이 아닌 오류 코드를 반환하려는 경우
  • 주 프로그램이 아닌 곳에서 프로그램을 종료하고 싶을 때

당신의 경우, 그것은 본체로부터의 단순한 복귀와 정확히 같은 일을 한다.

Java Language Specification에 따르면

프로그램 종료

프로그램은 모든 활동을 종료하고 다음 두 가지 중 하나가 발생할 때 종료된다.

데몬 스레드가 아닌 모든 스레드는 종료된다.

일부 스레드는 클래스 런타임 또는 클래스 시스템의 종료 방법을 호출하며, 보안 관리자가 종료 작업을 금지하지 않는다.

큰 프로그램(음, 적어도 이 프로그램보다 큰 프로그램)이 있고 실행을 끝내고 싶을 때 사용해야 한다는 뜻이다.

JVM에서 실행 중인 다른 프로그램이 있고 시스템을 사용하는 경우두 번째 프로그램도 닫을 거야예를 들어 클러스터 노드에서 Java 작업을 실행하고 클러스터 노드를 관리하는 Java 프로그램이 동일한 JVM에서 실행된다고 가정해 보십시오.작업에서 시스템을 사용하는 경우.종료하면 작업을 종료할 뿐만 아니라 "전체 노드를 종료"할 수 있다.관리 프로그램이 실수로 닫혔으므로 해당 클러스터 노드에 다른 작업을 보낼 수 없음.

따라서 시스템을 사용하지 마십시오.동일한 JVM 내의 다른 Java 프로그램에서 프로그램을 제어할 수 있으려면 종료하십시오.

시스템을 사용하십시오.전체 JVM을 의도적으로 종료하고 다른 응답(예: 종료 후크: Java 종료 후크, 명령줄 호출에 대한 0이 아닌 반환 값)에 설명된 가능성을 활용하려면 종료:Windows 배치 파일에서 Java 프로그램의 종료 상태를 가져오는 방법).

런타임 예외도 살펴보십시오.System.exit(num) 또는 런타임 던지기메인에서 예외?

참조URL: https://stackoverflow.com/questions/3715967/when-should-we-call-system-exit-in-java

반응형