2010-03-19 3 views
3

이 여기에 코드입니다 :창을 생성하지 않으면 타이머가 작동하지 않는 이유는 무엇입니까?

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.Timer; 

public class TimerSample { 
    public static void main(String args[]) { 
    new JFrame().setVisible(true); 
    ActionListener actionListener = new ActionListener() { 
     public void actionPerformed(ActionEvent actionEvent) { 
     System.out.println("Hello World Timer"); 
     } 
    }; 
    Timer timer = new Timer(500, actionListener); 
    timer.start(); 
    } 
} 

그것은 윈도우를 생성 한 후 주기적으로 터미널에서 인쇄에 "Hello World 타이머"(명령 프롬프트). 이 줄을 주석으로 쓰면 new JFrame().setVisible(true); 응용 프로그램이 명령 줄에 아무 것도 인쇄하지 않습니다. 왜?

ADDED :

나는 내가 제대로 답변을 이해 모르겠습니다. 늘어나는만큼 내가 이해, 타이머는 새로운 스레드를 시작합니다. 그리고이 새 스레드는 "주"스레드와 동시에 존재합니다. "메인"쓰레드가 끝났을 때 (모든 것이 끝났을 때 더 이상 아무것도 할 필요가 없다) 전체 애플리케이션은 (타이머에 의해 생성 된 "새로운"쓰레드와 함께) 종료된다. 맞지?

2 추가 :

전술 한 설명은 여전히 ​​모든 것을 설명하지 않습니다. 예를 들어, new JFrame().setVisible(true);에 주석을 달고 timer.start() 뒤에 try {Thread.sleep(20000);} catch(InterruptedException e) {};을 입력하면 프로그램이 작동합니다. 그래서 나는 그것을 이해하고 있습니다. 잠을 자면 타이머가 생성 한 스레드가 존재할 수 있도록 "메인"스레드가 바쁘게 유지됩니다. 그러나 new JFrame().setVisible(true);은 "메인"을 차지하지 않습니다. 내가 아는 한, Timer와 같은 자체 스레드를 생성한다. 그래서, 왜 JFrame의 스레드가 주 스레드 및 타이머 스레드없이 존재할 수 있습니까?

+1

을 다음 timer를 시작하고 타이머가 살아 남기 위해 메인 스레드의 원인에 대해 당신이 충분히 잠을 두 번째 예에서

. 그래서이 경우 나는 Timer가 데몬 쓰레드를 사용하고 있다고 의심합니다. 따라서 "메인"쓰레드가 끝나면 데몬 쓰레드와 JVM이 종료됩니다. 반면에 데몬 스레드가 아닌 자신 만의 스레드를 만들면 "메인"스레드와 비 데몬 스레드가 모두 완료 될 때까지 JVM이 종료되지 않습니다. Thread.setDaemon()을 참조하십시오. –

답변

1

타이머 기능은 창 이벤트 루프에서 호출됩니다 (크기 조정, 이동, 다시 그리기 등의 작업도 처리됩니다). 외관상으로는 창이 숨겨지면 이벤트 루프가 실행되지 않습니다.

이것은 잘못되었습니다. 대신 Frank의 대답을 확인하십시오.

+0

그러나 "window event loop"에서 호출되는 이유는 무엇입니까? JFrame이 Timer에 어떻게 든 연결되어있는 코드에는 아무 것도 표시되지 않습니다. – Roman

+1

-1, 창을 숨기는 것이 아니라 창을 만드는 것이 아닙니다. 어떤 창도 만들어지지 않으면 메인 메서드가 종료됩니다. 내 문제는 여기를 참조하십시오. 내 대답 참조) – Frank

5

당신은 요점을 놓치고 있습니다. Timer는 사용자가 만든 창과 독립적이며 창 생성 행을 주석 처리 할 때도 작동합니다.

그러나 보지 못한 것은 : timer.start() 이후 메인 프로그램이 종료되므로 프로그램 실행이 종료되고 타이머와 함께 진행됩니다.

끝 부분에 Thread.sleep(20000); (필요한 예외 처리 포함) 또는 약간의 시간이 소요되는 다른 코드를 추가하면이를 확인할 수 있습니다. 그런 다음 타이머는 창을 만들지 않고도 올바르게 작동합니다.

요점은 아무 것도 표시되지 않더라도 JFrame이 활성 상태로 유지되며 타이머가 계속 작동한다는 것입니다.

+0

Frank, 주 프로그램 "timer.start (종료)"에서 무엇을 의미합니까? timer.start()는 주 프로그램 앞에 있지만 주 프로그램에는 존재하지 않습니다. – Roman

+0

"프로그램 실행이 종료되었습니다"란 무엇을 의미합니까? 종료되면? 내 프로그램을 시작하고 끝내기 전에 작동합니다 (창을 닫고 명령 프롬프트에서 Ctrl-C를 누르면). – Roman

+0

타이머가 절전 모드와 다르게 작동합니다. 절전 모드는 지정된 시간 동안 코드를 일시 중지 한 후 다음 줄을 실행할 수있게합니다. 타이머는 차단하지 않으며 해당 시간이 경과하면 이벤트를 트리거합니다. 프레임이 있으면 메인 완료 후에 프로그램에서 다른 일이 일어나지 만 시간이 지나기 전에 프로그램이 종료됩니다. – unholysampler

1

각 타이머 오브젝트에 대응하여 순차적으로, 타이머의 모든 작업을 실행하는 데 사용 이다 단일 배경 스레드이다. Timer 객체의 마지막 라이브 참조 후

은 사라지고 모든 뛰어난 작업 스레드가 정상적으로 종료 실행, 타이머의 태스크 실행을 완료 한 (그리고 쓰레기 수집의 대상이된다). 그러나 이로 인해 임의로 길어질 수 있으므로 걸릴 수 있습니다.기본적으로 작업 실행 스레드는 을 데몬 스레드로 실행하지 않으므로 에서 응용 프로그램을 종료하는 데는 을 종료 할 수 있습니다. 호출자가 타이머 작업 실행 스레드를 빠르게 종료하려는 경우 호출자는 타이머의 cancel 메소드를 호출해야합니다. 1

그렇다면 java.util.Timer는 요청할 수있는 javax.swing.Timer와 어떤 관련이 있습니까? java.util.Timer : V 1.3에서

또 다른 Timer 클래스는 Java 플랫폼에 추가되었습니다. 모두 그와 javax.swing.Timer 그래서 타이머에 대한 마지막 참조하여 타이머 전에 멀리 정말 시작 간다 ... 당신이 알 경우 주요 방법은 즉시 완료 같은 기본 기능을 2

을 제공 timer.start();으로 전화를 걸고 타이머가 시작될 때까지 메인 스레드를 활성화시키지 않으면 타이머가 시작되지 않을 수 있습니다.

첫 번째 예에서는 JFrame이 주 스레드를 계속 유지합니다. 남아있는 유일한 스레드가 데몬 스레드가있는 경우 JVM이 종료

public static void main(String args[]) { 
     //new JFrame().setVisible(true); 
     ActionListener actionListener = new ActionListener() { 
      public void actionPerformed(ActionEvent actionEvent) { 
       System.out.println("Hello World Timer"); 
      } 
     }; 
     Timer timer = new Timer(500, actionListener); 
     timer.start(); 
     try { 
      Thread.sleep(500);//<--- the timer will still die 
      Thread.sleep(100);//<--- sleep for another 100 and the timer will start printing although you can't rely on it 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
관련 문제