按计划或条件运行代码

时间:2017-08-08 11:08:17

标签: java timertask

我有一个要求,我必须实时读取队列中的数据。使用迭代器读取数据,我还将保留从队列中读取的数据的计数。我将把数据写入文件。

EndProcess :我将使用时间戳重命名此文件,然后在两个条件下将其移至另一个位置(以先到者为准)。

  1. 当读数达到500并且计时器未完成时。
  2. 当读取计数小于500但已经过了特定时间(以分钟为单位)时
  3. 方案:

    • 首次遇到(1)时,我重置读取计数并运行EndProcess, 重置计时器,然后再次开始从队列中读取。
    • 第一次遇到(2)时,我将停止从队列中读取,运行 EndProcess,重置时间计时器,然后恢复轮询队列 消息。

    这就是我的代码现在的样子:

    while (dataSourceIterator.hasNext()) {
                while (recordCount < recordsPerFile) {
                    try {
                        inputPayload = dataSourceIterator.next();
                        if (inputPayload != null) {
                            log.info("Payload ::" + inputPayload.toString());
                            fileTarget.load(inputPayload);
                            fileTarget.commit();
                            recordCount++;
                        } else {
                            log.info("Input Payload is null.");
                        }
                    } catch (DataTargetException dataTargetException) {
                        throw new AbortException("Aborting" + dataTargetException.getMessage());
                    } catch (Exception exception) {
                        throw new AbortException("Aborting " + exception.getMessage());
                    }
                }
                recordCount = 0;
                renameFile();
                moveFile();
    }
    

    现在我决定使用TimerTask来实现计时功能。但看起来TimerTask没有重置计时器的选项,我只能取消它。

    请帮我处理第二种情况。此外,使用计时器任务的主要原因是,如果队列中只有较少的消息,则不等待500条消息。这就是为什么我们需要一个计时器。

    此外,不应发生在将500条消息读入文件之前完成计时器的情况。读取计数优先于计时器。

    编辑:即使dataSourceIterator.hasNext()变为false,此代码也会一直运行,直到队列中有消息为止。因此,更像是hasNext()将起作用,就像它总是如此。

    编辑2:所以我认为TimerTasks是要走的路。以下是我现在的解决方案:

        MyTimer task = new MyTimer("Timer");
    
        Timer timer = new Timer();
        timer.schedule(task, 0, 5000);
    
        int processed = 0;
        int recordsPerFile = 5;
        while (true) {
            while (processed < recordsPerFile) {
                System.out.println("processing " + processed);
                if (processed == 3) {
                    Thread.sleep(15000);
                } else {
                    Thread.sleep(500);
                }
    
                processed++;
            }
            processed = 0;
            task.setTaskStartedBy("CODE");
            task.run();
            task.cancel();
            timer = new Timer();
            task = new MyTimer("Timer");
            timer.schedule(task, 10000, 5000);
        }
    
    ---------------------------
    
    class MyTimer extends TimerTask {
    
        public String taskStartedBy;
    
        public MyTimer(String taskStartedBy) {
            this.taskStartedBy = taskStartedBy;
        }
    
        @Override
        public void run() {
            System.out.println("~End Process~ -- Started by " + taskStartedBy);
        }
    
        public String getTaskStartedBy() {
            return taskStartedBy;
        }
    
        public void setTaskStartedBy(String taskStartedBy) {
            this.taskStartedBy = taskStartedBy;
        }
    
    }
    

    在这里,我模拟了等待15秒以通知代码消息已修复。我可以看到由TIMER启动的计时器运行。如果删除了15秒,我可以看到CODE启动的计时器正在运行。

    请告诉我这种方法是否正确,是否适用于生产环境。如果还有其他更好的方法,请告诉我吗?

1 个答案:

答案 0 :(得分:0)

计时器运行时,计时器会自行重置。因此,例如,如果您希望每10分钟运行一次任务,则只需每10分钟安排一次。每次运行后都不必将其重置为零。这是自动的。

Timer t = new Timer("Read Data");
t.scheduleAtFixedRate(yourTaskObject,
                       Calendar.getInstance().getTime(),
                       60000); //runs once in 10 minutes