[英]Forcing Thread to execute an operation every day at specific time
作為構建優惠券系統的任務的一部分,我正在研究一項構建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
使用Date類,只需使用substring方法獲取星期幾並檢查是否相同。 如果不是,那么新的一天到來了。
這是您的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
}
}
希望對您有所幫助:)
我不確定您是否可以100%確定線程在指定時間准確運行(這取決於許多因素,例如OS,系統負載等)。 話雖如此,請查看一下scheduleAtFixedRate
方法中的ScheduledExecutorService 。 它提供了一個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包。 您會在其中找到很多好吃的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.