java - 强制线程每天在特定时间执行操作

标签 java multithreading

作为构建优惠券系统任务的一部分 我正在做一个任务来构建一个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/

相关文章:

c++ - 在这种情况下是否需要内存屏障或只是一个 volatile

c# - 多个线程向一个列表添加元素。为什么列表中的项目总是比预期的少?

c - C 中的多线程问题

java - 如何对 Collection<T> 进行排序?

java - 在单节点群集上使用分布式缓存和FileReader

Java MySQL 查询问题

validation - java 日期验证

文本字段的 javafx 场景生成器 Action 处理程序

java - 线程初学者 : What's the point in using a super() method within the sub class's(extending Thread class) constructor?

multithreading - 使用 Delphi 掌握多线程需要哪些核心原则?