[java] Timer & TimerTask 대 Thread + Sleep in Java

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

주기적으로 (예 : 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 () 메서드는 방해없이 작업을 계속 실행합니다. 이것은이 둘 사이에서 무엇을 사용할지 결정하는 주요 의사 결정자가 될 수 있습니다.



답변

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

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

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


답변

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


답변

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


답변

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


답변

로부터 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. 수면 중에는 잠금이 해제되지 않지만 대기는 객체 대기가 호출 될 때까지 잠금을 해제합니다.

답변

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

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


답변

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

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

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