2016-03-02 113 views
0

作爲構建優惠券系統的任務的一部分 我正在構建一個用於構建支持優惠券系統數據庫的Java程序的任務。 我應該創建一個線程,在每天的開始(00:00:00或稍後)運行一項任務,該任務檢查數據庫中的哪些優惠券已過期並將其從數據庫中刪除。爲此,我不能使用實現調度程序和定時器的java庫和包。 我正在努力尋找一種方法來確保任務在需要的特定時間每天運行。強制線程在特定時間每天執行操作

這裏是我想出了到現在爲止(它只會在24周小時的間隔工作):提前

public class DailyCouponExpirationTask extends Thread { 

     // class fields 
     private boolean keepRunning; 
     private final long sleepTime; 
     private CompanyDBDAO companyDBDAO; 
     private CouponDBDAO couponDBDAO; 
     private CustomerDBDAO customerDBDAO; 

     // constructor 
     DailyCouponExpirationTask() { 
      keepRunning = true; 
      this.sleepTime = 24 * 60 * 60 * 1000; 
      companyDBDAO = new CompanyDBDAO(); 
      couponDBDAO = new CouponDBDAO(); 
      customerDBDAO = new CustomerDBDAO(); 
     } // end constructor 

     // class methods 
     // force the thread to stop 
     void stopRunning() { 
      keepRunning = false; 

      interrupt(); 
     } // end method stopRunning 

     // Runnable interface methods 
     // run 
     @Override 
     public void run() { 
      while (keepRunning) { 
       Date currentDate = new Date(new java.util.Date().getTime()); 
       Collection<Coupon> coupons = couponDBDAO.getAllCoupons(); 

       Iterator<Coupon> iterator = coupons.iterator(); 

       while (iterator.hasNext()) { 
        Coupon currentCoupon = iterator.next(); 

        if (currentDate.after(currentCoupon.getEndDate())) { 
         // remove coupon from database 
        } 
       } 

       try { 
        Thread.sleep(sleepTime); 
       } catch (InterruptedException e) { 
        if (keepRunning) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } // end method run 

    } // end class DailyCouponExpirationTask 

謝謝!

編輯:我想出了一個解決方案,我想聽聽你的想法和評論。 心中已經創建計算Thread的總睡眠時間,直到下一次例行任務迭代的方法:

// calculate sleep time until next coupons update task (1:00:00 next day) 
private long calculateSleepTime() { 
    Calendar currentTime = new GregorianCalendar(); 
    Calendar nextUpdateTime = new GregorianCalendar(); 

    nextUpdateTime.set(Calendar.HOUR_OF_DAY, 1); 
    nextUpdateTime.set(Calendar.MINUTE, 0); 
    nextUpdateTime.set(Calendar.SECOND, 0); 
    nextUpdateTime.set(Calendar.MILLISECOND, 0); 

    nextUpdateTime.add(Calendar.DAY_OF_MONTH, 1); 

    return nextUpdateTime.getTimeInMillis() - currentTime.getTimeInMillis(); 
} // end method calculateSleepTime 
+0

您可以使用Spring批處理來執行此操作 – Lathy

+0

爲什麼cronTab或WindowsService(取決於O.S)不適用於您? –

+0

@MrunalGosar 其實這是我給的任務。它應該在一天內運行一次,但我認爲如果它在用戶登錄系統之前的每天開始的夜間運行會更好。對於作業,我不應該使用外部庫,所以我試圖弄清楚是否可以使用基本的Java來完成。 –

回答

1

使用Date類,只需使用子方法來獲取星期,並檢查它是否是一樣的。如果不是,那麼新的一天已經到來。

這是你的run方法應該是什麼樣子:

public void run(){ 
while(true){ 

    Date d=new Date(); 
String day=d.toString().substring(0,3); 
for(;;){ 
try{ 
Thread.sleep(60000); 
Date date=new Date(); 
String currentday=date.toString().substring(0,3); 
if(day.equals(currentday)==false){break;} 
}catch(Exception e){System.out.println(e.getMessage());} 
    Date d=new Date(); 

} 
//Do things once a day 
} 
} 

希望這有助於:)

+0

首先,你會爲'睡眠'方法使用'for'循環,而不是隻傳遞毫秒代表整天?第二,根據我的理解,您的代碼在24小時的時間間隔內工作,但不是在需要時的特定時間。 –

+0

睡眠不釋放資源。保持線程永久運行的好方法是什麼? – Braj

+0

@NitzanM Just編輯答案。 – Paul

1

我不知道你是否能100%肯定,一個線程運行恰好在指定時間(這取決於很多因素,如操作系統,系統負載等)。 話雖如此,看看ScheduledExecutorService具體在scheduleAtFixedRate方法。它提供了一個API來定期安排執行。例如,你可以這樣做:

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); 
    long initialDelay = 1800; 
    long period = 3600; 
    TimeUnit timeUnit = TimeUnit.SECONDS; 
    executor.scheduleAtFixedRate(new Runnable() { 
     @Override public void run() { 
      //do something here 
     } 
    }, initialDelay, period, timeUnit); 

這樣做是什麼,安排1800秒後要執行的任務,然後每3600秒重複一次。 您必須記住,對於要執行的計劃操作,JVM必須保持運行。

我強烈推薦瀏覽javadocs的java.util.concurrent包。你會在那裏找到很多好東西。

+0

我知道我無法知道線程執行任務的確切時間,但幾分鐘左右的偏差將滿足要求。感謝您的回答,我將着眼於它! –

相關問題