2017-04-21 112 views
1

我想每天準確啓動ScheduledExecutorService,每天凌晨12點,Schedule必須在今天22/02/2017 00:00:00(UTC TIME)開始,任何人都可以告訴我是否我的代碼是否正確?ScheduledExecutorService每天晚上12點執行UTC時間

DateTime today = new DateTime().withTimeAtStartOfDay(); 
     DateTime startOfTommorrow = today.plusDays(1).withTimeAtStartOfDay(); 

     Long midnight = startOfTommorrow.getMillis(); 
     long midnights = (midnight/1000)/60; 
     final DateFormat nextDateTymFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

     System.out.println("***********************************"); 
     System.out.println("Schedule Updater "+nextDateTymFormat.format(new Date())); 
     System.out.println("today "+today); 
     System.out.println("startOfTommorrow "+startOfTommorrow); 
     System.out.println("midnight Long "+midnight); 
     System.out.println("***********************************"); 
     vitalScheduleThread.scheduleAtFixedRate(new Runnable() { 

      @Override 
      public void run() { 

       System.out.println("Hello vitalSchService !!"+nextDateTymFormat.format(new Date())); 

       Thread.currentThread().setName("vitalSchService"); 

       //sendMail(); 
       vitalSchedule.process(springContext); 
      } 
     }, midnight , 86400000 , TimeUnit.MILLISECONDS 

);

回答

1

由於您在調用日期時間方法時忽略區域作爲參數,因此您假設JVM的當前時區是您期望的UTC。不一定是真的。該JVM中任何應用程序的任何線程中的任何代碼都可以在運行時隨時更改默認值。相反,請始終指定您想要的/預期的區域。

您似乎正在使用喬達時間庫。該項目現在處於維護模式,團隊建議遷移到java.time類。

OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC); 
LocalDate today = now.toLocalDate(); 
LocalDate tomorrow = today.plusDays(1); 
OffsetDateTime tomorrowStart = OffsetDateTime.of(tomorrow , LocalTime.MIN , ZoneOffset.UTC); 
Duration d = Duration.between(now , tomorrowStart); 
long millisUntilTomorrowStart = d.toMillis(); 

而不是一個神祕的數字文字,如86400000,使用自我記錄呼叫。

TimeUnit.DAYS.toMillis(1) 

所以,你的調度應該是這樣的:

….scheduleAtFixedRate(
    new Runnable() { … } , 
    millisUntilTomorrowStart , 
    TimeUnit.DAYS.toMillis(1) , 
    TimeUnit.MILLISECONDS 
) 

對於整個天遞增,您可以不用這樣的精細粒度爲毫秒。由於各種原因,執行者不能以完美的時機運行。所以我可能會在幾分鐘內計算出來。但並不重要。

非常重要:您需要將Runnable的run方法的代碼放在任何異常的陷阱中。如果任何類型的例外要到達執行者,執行者將默默停止。沒有進一步的任務調度,也沒有警告。搜索堆棧溢出瞭解更多信息,包括答覆我。

你不解釋你稱之爲scheduleAtFixedRate的對象是什麼。所以這是代碼的重要組成部分,我們無法提供幫助,除非您發佈更多信息。我擔心你把它命名爲「線程」。該對象必須是ScheduledExecutorService的實現,而不是線程。

提示:避免在午夜時分運行。午夜時間很多事情都會發生在電腦上。例如,閏秒調整,許多Unix清理實用程序以及日常活動(如可能由初級管理員安排的備份)。等待五到十五分鐘的時間可能會避免麻煩和神祕的問題。

+0

嗨,是的,我的服務器時間總是UTC,稍後我會檢查你的更改,但請檢查我的代碼,並根據我在要求中提到的要求,讓我知道我的代碼是否正確 – kavie

+0

我正在嘗試警告您應該*不*假設您當前的默認時區始終爲UTC。這是一個程序員無法控制的事實。沒有必要依賴當前的默認區域,爲什麼冒這個風險呢?只需通過我的代碼中顯示的'ZoneOffset.UTC',就可以減少一個問題。你說的要求是在午夜UTC運行,而不指定時區是我看到的最大的風險。 –

+0

好吧讓我檢查一下 – kavie

相關問題