Timer & TimerTask 대 Thread + Sleep in Java


102

여기에서 비슷한 질문을 찾았지만 만족할만한 답변이 없었습니다. 그래서 다시 질문을 바꿔

주기적으로 (예 : 1 분 간격) 수행해야하는 작업이 있습니다. 절전 모드가있는 무한 루프가있는 새 스레드를 만드는 것과 달리 Timertask 및 Timer를 사용하여이를 수행 할 때의 이점은 무엇입니까?

timertask-를 사용하는 코드 스 니펫

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

Thread 및 Sleep을 사용하는 코드 스 니펫

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

논리 실행이 간격 시간보다 더 많이 걸리는 경우 특정주기를 놓쳐도 걱정할 필요가 없습니다.

댓글 부탁드립니다 ..

업데이트 :
최근에 Timer와 Thread.sleep () 사용의 또 다른 차이점을 발견했습니다. 현재 시스템 시간이 11:00 AM이라고 가정합니다. 어떤 이유로 시스템 시간을 오전 10 시로 롤백하면 타이머가 오전 11시에 도달 할 때까지 작업 실행을 중지하지만 Thread.sleep () 메서드는 방해없이 작업을 계속 실행합니다. 이것은이 둘 사이에서 무엇을 사용할지 결정하는 주요 의사 결정자가 될 수 있습니다.


21
순서 : Timer 및 TimerTask는 더 이상 사용되지 않으며 해당 지점이 여전히 유효하지만 ExecutorService로 효과적으로 대체되었습니다.
skaffman

팁을 주셔서 감사합니다. ExecutorService를 사용하기로 결정했습니다. :)
Keshav

답변 해주셔서 감사합니다. 확실히 더 많은 이해를주었습니다!
Keshav

6
타이머는 더 이상 사용되지 않으며 단일 스레드 만 필요한 경우 선호됩니다. ( java.sun.com/javase/6/docs/api/java/util/Timer.html )
Justin

2
Timer 및 TimerTask는 ExecutorService가 존재하지 않는 JME 환경에서 여전히 유용합니다 (JME Java 1.3 기반 이후 ...).
スーパーファミコン

답변:


67

TimerTask의 장점은 의도를 훨씬 더 잘 표현하고 (즉, 코드 가독성), 이미 cancel () 기능이 구현되어 있다는 것입니다.

자신의 예제뿐만 아니라 더 짧은 형식으로도 작성할 수 있습니다.

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);

타이머가 Everyday, 2 특정 시간 9pm 및 9am에 사용되는 경우 값을 제공하는 방법은 무엇입니까? 위의 코드에 ... @Zed?
gumuruh

12

Timer / TimerTask는 작업 실행 시간도 고려하므로 좀 더 정확합니다. 또한 다중 스레딩 문제 (예 : 교착 상태 방지 등)를 더 잘 처리합니다. 물론 일반적으로 직접 만든 솔루션 대신 잘 테스트 된 표준 코드를 사용하는 것이 좋습니다.


5

이유는 모르겠지만 내가 작성중인 프로그램은 Timers를 사용하고 있었고 스레드 / 수면 문제 해결로 변경하면 힙 크기가 지속적으로 증가했습니다.


9
타이머는 지속적으로 업데이트되는 작업 대기열을 만듭니다. 타이머가 완료되면 즉시 가비지 수집되지 않을 수 있습니다. 따라서 더 많은 Timer를 생성하면 힙에 더 많은 객체 만 추가됩니다. Thread.sleep ()은 스레드 만 일시 중지하므로 메모리 오버 헤드가 매우 낮습니다.
Darryl Gerrow 2013 년

4

스레드가 예외를 받고 죽으면 문제입니다. 그러나 TimerTask가 처리합니다. 이전 실행의 실패와 관계없이 실행됩니다.


4

로부터 Timer 문서 :

Java 5.0은 java.util.concurrent 패키지를 도입했으며 그 안에있는 동시성 유틸리티 중 하나는 주어진 속도 또는 지연으로 작업을 반복적으로 실행하기위한 스레드 풀인 ScheduledThreadPoolExecutor입니다. 다중 서비스 스레드를 허용하고 다양한 시간 단위를 허용하며 TimerTask를 서브 클래 싱 할 필요가 없기 때문에 Timer / TimerTask 조합을 효과적으로 대체 할 수 있습니다 (Runnable 구현). 하나의 스레드로 ScheduledThreadPoolExecutor를 구성하면 Timer와 동일합니다.

그래서 ScheduledThreadExecutor대신 선호 Timer:

  • Timer타이머의 모든 작업을 순차적으로 실행하는 데 사용되는 단일 백그라운드 스레드를 사용합니다. 따라서 작업은 빨리 완료되어야하며 그렇지 않으면 후속 작업의 실행이 지연됩니다. 그러나의 경우 ScheduledThreadPoolExecutor여러 스레드를 구성 할 수 있으며 ThreadFactory.
  • TimerObject.wait(long)방법 을 사용하므로 시스템 시계에 민감 할 수 있습니다 . 하지만 ScheduledThreadPoolExecutor그렇지 않습니다.
  • TimerTask에서 발생하는 런타임 예외는 특정 스레드를 종료하므로 ScheduledThreadPoolExecutor다른 작업에 영향을주지 않도록 처리 할 수있는 경우 Timer가 종료됩니다 .
  • Timer 제공 cancel타이머를 종료하고 예약 된 작업을 삭제하는 방법을 하지만 현재 실행중인 작업을 방해하지 않고 완료되도록합니다. 그러나 타이머가 데몬 스레드로 실행 중이면 취소 여부에 관계없이 모든 사용자 스레드 실행이 완료되는 즉시 종료됩니다.

타이머 대 Thread.sleep

타이머를 활용 Object.wait하고 있으며Thread.sleep

  1. 대기 ( wait) 스레드에 알림을 보낼 수 있습니다 (사용notify 다른 스레드에 의해 ) 할 수 있지만 휴면중인 스레드는 알 수 없으며 인터럽트 만 가능합니다.
  2. 대기 (및 알림)는 모니터 개체에서 동기화 된 블록에서 발생해야하지만 절전 모드는 그렇지 않습니다.
  3. 수면 중에는 잠금이 해제되지 않지만 대기는 객체 대기가 호출 될 때까지 잠금을 해제합니다.

매우 유용한 정보와 더불어 무한 루프에서 Thread.sleep을 사용하면 적은 시간 지연으로 CPU 사용량이 높아질 수 있습니다.
Amir Fo

3

자바 쓰레드와 sleep메소드를 사용하여이 작업을 관리하는 것에 대한 한 가지 중요한 주장이 있습니다. 당신이 사용하는 while(true)루프에 무기한 머물면서 잠을 바꾸어 스레드를 최대 절전 모드. NewUploadServer.getInstance().checkAndUploadFiles();동기화 된 리소스를 차지 하면 어떨까요? 다른 스레드는 이러한 리소스에 액세스 할 수 없으며 기아 상태가 발생하여 전체 응용 프로그램이 느려질 수 있습니다. 이러한 종류의 오류는 진단하기 어렵고 존재를 방지하는 것이 좋습니다.

다른 aproach는 당신에게 중요한 코드의 실행을 촉발합니다. 즉, 다른 스레드가 리소스를 사용하도록하는 동안 당신 NewUploadServer.getInstance().checkAndUploadFiles();run()메소드를 호출함으로써 TimerTask.


16
나는이 주장을 이해하지 못한다. 두 선택 모두 스레드에서 동일한 메서드를 시작하고 두 선택 모두 실행을 기다리는 동안 스레드에서 잠자고 있습니다. 두 가지 선택 사이에는 기아 차이가 없습니다.
satur9nine 2011-07-22

2

나는 당신의 문제를 이해한다고 생각합니다. 나는 매우 비슷한 것을보고 있습니다. 30 분마다, 그리고 이틀마다 반복되는 타이머가 있습니다. 내가 읽은 내용과 내가 본 댓글을 보면 모든 작업이 완료되지 않았기 때문에 가비지 수집이 실행되지 않는 것처럼 보입니다. 타이머가 잠자기 상태 일 때 가비지 수집이 실행될 것이라고 생각하지만 나는 그것을 보지 못하고 문서에 따르면 그렇지 않습니다.

새 스레드 생성이 완료되고 가비지 수집이 가능하다고 생각합니다.

누군가 나를 틀렸다는 것을 증명하십시오. 내가 물려받은 것을 다시 쓰는 것은 고통 스러울 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.