As part of an assignment to build a coupon system I'm working on an assignment to build a Java program to support coupon system database. I'm supposed to create a Thread that runs a task at the beginning of every day (00:00:00 or a bit later) that checks which of the coupons in the database expired and removes them from database. For this I can't use java libs and packages that implement schedulers and timers. I'm struggling to find a way to assure that the task runs every day at the specific time it needs to be.
Here is what I came up with till now (it will only work in 24 hours intervals):
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
Thanks in advance!
EDIT: I've come up with a solution and I would like to hear your thoughts and comments about it.
I'v created a method to calculate the overall sleep time of the Thread
until next routine task iteration:
// 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 :(得分:1)
使用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
}
}
希望这有助于:)
答案 1 :(得分:1)
我不确定你是否可以100%确定一个线程在指定的时间完全运行(它取决于许多因素,如操作系统,系统负载等)。
话虽如此,请专门针对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必须保持运行。
我强烈建议浏览java.util.concurrent包的javadoc。你会在那里找到很多好东西。