Как реализовано планирование задач? - PullRequest
3 голосов
/ 23 ноября 2010

Я проделал большую часть работы по извлечению некоторых данных из веб-службы, но теперь у меня возникла проблема с планированием запросов к нему, и я не совсем уверен, с чего начать.

Я слушаю очередь jms для событий, и после получения события мне нужно сделать запрос к веб-службе по истечении некоторого времени. Продолжительность варьируется в зависимости от атрибутов события. Если веб-сервис возвращает false, мне нужно продолжать планировать запросы, пока он не вернет true.

Я думал о создании запроса поиска в очереди при получении события или ложного ответа, но это не кажется идеальным - я буду постоянно потреблять сообщения, проверяя время, чтобы увидеть, должен ли запрос сделать еще и положить его в очередь, если нет.

Если у кого-нибудь есть совет, как решить такую ​​проблему, я бы очень признателен.

Ответы [ 4 ]

6 голосов
/ 23 ноября 2010

Во-первых, убедитесь, что вы храните события в очереди в том порядке, в котором они должны быть выполнены.Это гарантирует, что вам нужно только посмотреть на начало очереди, чтобы увидеть, когда должно быть запланировано следующее событие.Для этого вы можете использовать PriorityQueue.

Ваш поток для обработки событий будет опрашивать элементы из этой очереди и обрабатывать их.Сделайте так, чтобы он заглянул в головной элемент и выяснил, когда нужно запустить следующее событие.Выберите объект для использования в качестве объекта блокировки и вызовите основной поток Object.wait(long) для этого объекта, передавая метод количество миллисекунд до тех пор, пока не потребуется запустить следующее событие.

Если приходит новый потокдобавьте его в очередь в соответствующем месте.Если элемент находится в начале очереди, это означает, что поток должен проснуться раньше.Вызовите Object.notifyAll() для объекта блокировки, чтобы активировать поток обработки.Он увидит, что нечего обрабатывать, и вернется ко сну на соответствующее время.

public class ProcessingQueue extends Thread {

  private PriorityQueue<Task> tasks;  

  private volatile boolean isRunning = true;

  public void addTask(Task t) {
    synchronized (this.tasks) {
      this.tasks.offer(t);
      // this call requires synchronization to this.tasks
      this.tasks.notifyAll();
    }
  }

  public void shutdown() {
    this.isRunning = false;
    synchronized (this.tasks) {
      this.notifyAll();
    }
  }

  public void run() {
    while (this.isRunning) {
      synchronized (this.tasks) {
        Task t = this.tasks.peek();
        // by default, if there are no tasks, this will wake every 60 seconds
        long millisToSleep = 60000;
        // getExecuteMillis() should return the time, in milliseconds, for execution
        if (t != null) millisToSleep = t.getExecuteMillis() - System.currentTimeMillis();
        if (millisToSleep > 0) {
          try {
            // this line requires synchronization to this.tasks
            // and the lock is removed while it waits
            this.tasks.wait(millisToSleep);
          } catch (InterruptedException e) {
          }
        }
        t = this.tasks.poll();
        if (t != null) {
          t.execute();
        }
      }
    }
  }
}
4 голосов
/ 23 ноября 2010

Я согласен с использованием сторонней библиотеки. Я использую кварцевые рамки для этого. http://www.quartz -scheduler.org /

2 голосов
/ 23 ноября 2010

Используйте существующий планировщик OSS: http://java -source.net / open-source / job-scheduler

Вы всегда можете свернуть свои собственные, но я бы не рекомендовал его,

Одна важная особенность планировщика должна состоять в том, что он переживает перезапуск / сбой.

0 голосов
/ 02 декабря 2010

Я решил пойти с Spring Task Scheduling , который был представлен в версии 3. Он предлагает объединение в пул, планирование на основе обоих моментов во времени и интервалах, и, если требуется дополнительная настройка, он имеетвариант cron.Я не углублялся в глубины того, что может быть достигнуто с помощью Quartz, но он также предлагает интеграцию с этим.

...