作为构建优惠券系统任务的一部分 我正在做一个任务来构建一个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
直到下一次例行任务迭代的总体 sleep 时间:
// 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
最佳答案
我不确定您是否可以 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 必须保持运行。
我强烈建议浏览 java.util.concurrent 的 javadoc包裹。你会在那里发现很多好东西。
关于java - 强制线程每天在特定时间执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35745132/