簡體   English   中英

強制線程每天在特定時間執行操作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM