有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

共 (2) 个答案

  1. # 1 楼答案

    使用Date类,只需使用substring方法获取一周中的某一天,并检查它是否相同。如果不是这样,那么新的一天已经到来

    以下是您的跑步方法的外观:

    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
    }
    }
    

    希望这有帮助:)

  2. # 2 楼答案

    我不确定你是否能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必须保持运行

    我强烈建议浏览javadocs以获得java.util.concurrent包。你会发现里面有很多好吃的东西