2010-05-27 6 views
1

나는 하루 중 특정 순간에 실행해야하는 타이머 스레드가 있습니다. 데이터베이스를 사용한 증분 복제. 지금은 1 시간 15 분, 1 시간 30 분, 1 시간 45 분으로 실행됩니다. 이 프로세스는 TimerRunner.initialize() 때 서버가 시작를 호출 TimerRunner.destroy()를 호출하여 시작x : 00 x : 15 x : 30 및 x : 45에서 실행되는 스레드를 만드는 방법 2:00에서 다른 작업 수행

public class TimerRunner implements Runnable { 

    private static final Semaphore lock = new Semaphore(1); 

    private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 

    public static void initialize() { 
     long delay = getDelay(); 
     executor.schedule(new TimerRunner(), delay, TimeUnit.SECONDS); 
    } 

    public static void destroy() { 
     executor.shutdownNow(); 
    } 

    private static long getDelay() { 
     Calendar now = Calendar.getInstance(); 
     long p = 15 * 60; // run at 00, 15, 30 and 45 minutes past the hour 
     long second = now.get(Calendar.MINUTE) * 60 + now.get(Calendar.SECOND); 
     return p - (second % p); 
    } 

    public static void replicate() { 
     if (lock.tryAcquire()) { 
      try { 
       Thread t = new Thread(new Runnable() { 
        public void run() { 
         try { 
          // here is where the magic happens 
         } finally { 
          lock.release(); 
         } 
        } 
       }); 
       t.start(); 
      } catch (Exception e) { 
       lock.release(); 
      } 
     } else { 
      throw new IllegalStateException("already running a replicator"); 
     } 
    } 

    public void run() { 
     try { 
      TimerRunner.replicate(); 
     } finally { 
      long delay = getDelay(); 
      executor.schedule(new TimerRunner(), delay, TimeUnit.SECONDS); 
     } 
    } 

} 

이 괜찮 노력하고 내가 가지고있는 코드입니다.

하루 중 특정 순간 (예 : 오전 2시)에 실행하려는 전체 복제 프로세스 (증분과 반대)를 만들었습니다. 어떻게 이렇게 위의 코드를 변경하겠습니까? 나는 마치 2:00 경에 마치 지금은 전체 복제를했기 때문에 오랜 시간이 걸렸을 때와 같이 매우 간단해야한다고 생각합니다. 그렇지만 지금은 제대로 할 수 없습니다.

때로는 복제 프로세스를 완료하는 데 시간이 오래 걸리는 것을 유의하십시오. 때로는 15 분을 초과하여 오전 2 시경에 달리는 데 문제가 있습니다.

답변

5

IMHO가 다른 경우, 동일한 실행 파일이 아니어야합니다. 각각의 특정 동작을 가진 일반 추상 클래스와 두 개의 하위 클래스를 만듭니다. 그런 다음 적절한 시간에 적절한 스레드를 예약하도록 예약 논리를 설정하십시오.

그렇지 않으면 두 가지 책임을지고 예약에 대해 알아야 할 개체가 있습니다.

또한 개인적으로 현재 getDelay() 및 상태 (예 : 최근에 실행 된 내용)를 유지 관리하는 일부 복제 스케줄러 관리자 객체에서 일정 논리를 가져올 수도 있습니다.

마지막으로, 스케쥴러 용 라이브러리를 사용하고 싶을 수도 있습니다. 필자는 휠을 재발 명하고있는 것처럼 느낍니다.

3

기존 스케쥴러를 사용하지 마십시오. 기존 스케쥴러를 사용하지 마십시오.

Java에서이 작업을 수행하려면 quartz을 사용하고 다른 스케줄에서 실행되는 증분 백업과 전체 백업에 대해 2 개의 개별 태스크를 예약하십시오.

그러나 귀하의 경우에는 간단한 cron 스크립트를 사용해도됩니다. Windows에서 실행중인 경우 Windows 도움말 파일에서 Scheduled Tasks을 검색하십시오.

*/15 0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 * * * /path/to/run-incremental-backup.sh 
15,30,45 1 * * * /path/to/run-incremental-backup.sh 
0 1 * * * /path/to/run-full-backup.sh 

당신이 스크립트 설치 Java 환경 쉘과 작업을 담당 자바 프로그램을 실행에 :

편집 여기
동시에 모두 전체 및 증분 실행 피한다은 crontab이다.

쿼츠 일정은 매우 미세 조정될 수 있습니다. 표준 스케줄러 중 하나는 완전히 crontab을 모방합니다. 나는 이것을 독자를위한 운동으로 남겨 둔다.

나는 전체 백업을 오전 1시에 실행하도록 예약 했으므로 아래의 이유를 참조하십시오.일광 절약 시간 ON

참고
나는 그렇지 현지 시간 확인, 당신이 일광 절약 시간이없는 몇 행운아 중 하나입니다 경우, 어디에 세계에서 모르는 지역 당국. 여기 북미 표준에서 일광은 오전 2시에 발생하고 주간 표준은 오전 3시에 발생하므로 전체 백업이 오전 2시에 예정되어 있다면 일년에 한 번 (S에서 D) 전체 백업이 예정됩니다 달리기 (D에서 S)는 두 번 실행됩니다.

+0

두 스케줄러의 한 가지 문제점은 오전 2시에 증분과 전체를 실행해야하지만 전체가 필요하다는 것입니다. 두 가지 예정된 프로세스 간의 경쟁 조건을 확인하는 방법? – rmarimon

+0

@rmarimon. 나는 당신의 의견을 해결하기 위해 내 대답을 업데이 트했습니다. –