2009-06-22 5 views
19

Java 명령 행 프로그램을 정상적으로 종료하는 다른 방법에 관심이 있습니다. kill 신호를 보내는 것은 옵션이 아닙니다.Java 명령 행 프로그램을 정상적으로 종료하는 가장 좋은 방법

나는 몇 가지 다른 접근 방식을 생각할 수 있습니다.

  1. 포트를 열고 연결을 기다립니다. 하나가 만들어지면 정상적으로 종료됩니다.
  2. 생성 될 파일을 확인한 다음 종료하십시오.
  3. 터미널에서 "execute shutdown"과 같은 입력을 읽습니다.

프로그램 출력이 화면에 나타나기 때문에 세 번째 것은 이상적이지 않습니다. 첫번째 것은 너무 많은 노력이 필요합니다 (저는 게으르다). 대부분의 프로그래머는 두 번째 옵션을 사용합니까? 그렇지 않다면, 다른 가능한/우아한/단순한 무엇입니까?

+0

프로세스가 Java 명령 행 프로그램을 종료한다는 뜻입니까? – Tom

+2

kill 신호를 보내지 않는 이유는 무엇입니까? 아래 답변에서 언급했듯이 종료 신호음을 사용하여 종료 신호를 정상적으로 잡아서 처리 할 수 ​​있습니다. – toluju

답변

2

처음 두 옵션은 구현이 간단합니다. 당신은 또한 JMX에 관한 것들을 사용할 수도 있습니다. Tomcat은 첫 번째 방법을 사용하고 두 개의 프로젝트에서 1과 2를 적용했습니다.

9

귀하는 귀하의 요구 사항을 충족시켜야 Runtime.getRuntime().addShutdownHook()을 사용해 볼 수 있습니다. 이 방법으로 gracefull 종료를 수행하기 위해 후크를 등록하여 정리를 수행 할 수 있습니다.

편집 새로운 가상 머신의 종료 훅을 등록

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) 공공 무효 addShutdownHook (스레드 후크).

  • 프로그램이 정상적으로 종료, 마지막 비 데몬 스레드가 종료 또는 종료가 (동등 System.exit와) 메서드 호출, 또는 : Java 가상 머신 이벤트 두 종류의에 대한 응답으로 종료
  • 가상 컴퓨터는^C과 같은 사용자 인터럽트 나 사용자 로그 오프 또는 시스템 종료와 같은 시스템 전체 이벤트에 대한 응답으로 종료됩니다.
+0

cntrl + c를 실행하면 작동하지 않습니다. –

+0

하지만 mike는 정상적으로 성능을 저하시키는 방법으로 ctrl + c를 누르면 모든 cmd 프로그램이 kill 신호로 종료됩니다. –

+0

당신이 언급 한 다른 옵션들도 없으므로, ctrl + c의 동작은 아마도 이러한 방법 중 하나를 결정하는 것과 관련이 없습니다. – Herms

16

이 뭔가를 시도 할 수 있습니다 :

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { /* 
     my shutdown code here 
    */ } 
}); 

편집 :

종료 훅이 응용 프로그램의 아래로 종료를 수행하지 않습니다. 대신 개발자는 시스템 종료시 원하는 모든 정리 작업을 수행 할 수있는 방법을 제공합니다. Runtime에 대한 JavaDoc을에서

(이 방법을 사용하려는 경우 좋은 읽기) :

셧다운 후크는 단순히 초기화하지만 시작하지 않은 스레드입니다. 가상 시스템이 종료 시퀀스를 시작하면 등록되지 않은 모든 종료 훅이 지정되지 않은 순서로 시작되어 동시에 실행됩니다. 모든 후크가 끝나면 종료시 파이널 라이즈가 활성화 된 경우 모든 활성화되지 않은 파이널 라이저를 실행합니다. 마지막으로 가상 컴퓨터가 중단됩니다. ...

+0

그 프로그램을 어떻게 종료합니까? –

+0

이 (가) 편집되었습니다. 나는 당신의 질문에 그 주소가되기를 바랍니다. – akf

+0

run 메소드에 @Override 주석을 사용해야하지 않습니까? –

5

첫 번째 포트에서 수신 대기하는 두 번째 옵션 (즉, 파일을 확인하는 것)의 이점은 보안에 대한 가능성이 있다는 것입니다.

적절한 사용자 만 프로그램을 닫을 수 있도록 파일이 만들어진 디렉터리에 대한 사용 권한을 설정할 수 있습니다. 포트를 경청하면 모든 사용자가 포트에 연결할 수 있습니다.

+0

클라이언트 IP 주소를 기반으로 들어오는 호출을 제한 할 수 있습니다. 예를 들어 localhost에서만 연결을 허용합니다. 적절한 IP 주소 일 때만 종료하고 그렇지 않으면 연결을 닫고 새 포트를 계속 청취합니다. – akarnokd

+0

@ kd304 - IP 주소를 제한하면 로컬 시스템의 모든 사용자가 프로세스를 종료 할 수 있습니다. 디렉토리에 대한 사용 권한을 설정하면 프로세스에 대한 특정 사용자 제어 만 허용 할 수 있습니다. –

0

종료 훅을 사용하는 것이 좋습니다. 표준 OS 도구를 사용하여 프로그램을 제어 할 수 있습니다. 또한 외부 리소스 (디스크, 포트 등)에 대한 추가 액세스가 필요하지 않습니다.

2

소켓 버전으로 가고 싶다면 구현이 매우 간단합니다. 여기 코드는 다음과 같습니다

ServerSocket server = new ServerSocket(8080); 
System.out.println("Socket listening!"); 
server.accept(); 
System.out.println("Connection received!"); 

당신은 쉽게 당신이 당신의 프로그램을 시작하고 그것을 종료를 시작할 전역 상태를 수정할 수있는 별도의 스레드에서이 코드를 포함 할 수있다.

1

JMX 구성 요소를 고려하십시오. 그런 다음 JConsole을 로컬로 또는 네트워크를 통해 연결하고 구성 요소와 통신 할 수 있습니다. 그런 다음 구성 요소가 프로그램을 올바르게 종료 할 수 있습니다.

Java 6 u 10 이상에서는 JVisualVM에서도 동일한 작업을 수행 할 수 있습니다.

관련 문제