Таймер поворота в сочетании с возможной долгосрочной фоновой задачей - PullRequest
0 голосов
/ 07 апреля 2010

Мне нужно многократно выполнять задачу, которая затрагивает объекты, связанные как с графическим интерфейсом, так и без него. Одно предостережение заключается в том, что никакое действие не должно выполняться, если предыдущее задание не было выполнено при запуске следующего события таймера. Сначала я хочу использовать SwingTimer в сочетании с объектом javax.swing.SwingWorker. Общая установка будет выглядеть следующим образом.

class
{
    timer = new Timer(speed, this);
    timer.start(); 

    public void actionPerformed(ActionEvent e) 
    {
        SwingWorker worker = new SwingWorker() {
            @Override
            public ImageIcon[] doInBackground() {
                // potential long running task
            }

            @Override
            public void done() {
                // update GUI on event dispatch thread when complete
            }
    }
}

Некоторые потенциальные проблемы, которые я вижу при таком подходе:

1) Несколько SwingWorkers будут активны, если работник не завершил работу до следующего запуска ActionEvent по таймеру.

2) SwingWorker предназначен для выполнения только один раз, поэтому удержание ссылки на работника и повторное использование (не так ли?) Жизнеспособного варианта.

Есть ли лучший способ добиться этого?

Ответы [ 3 ]

1 голос
/ 08 апреля 2010

Почему вы используете таймер? Было бы проще поддерживать работника все время, делая паузу с помощью sleep () всякий раз, когда задача занимает слишком мало времени для выполнения. Вы все еще можете обновить вещи в потоке отправки событий, используя что-то вроде следующего:

Thread background = new Thread(new Runnable() {
  public void run() {
    while ( ! stopRequested ) {
       long start = System.currentTimeMillis();
       // do task
       long elapsed = start - System.currentTimeMillis();

       SwingUtilities.invokeLater(new Runnable() { 
          public void run() { 
             // update UI
          }
       });
       if (elapsed < tickTime) {
          Thread.sleep(tickTime - elapsed);
       }
    }
  }
}.start();
1 голос
/ 08 апреля 2010

Для (1) может быть полезен метод scheduleAtFixedRate() для ScheduledThreadPoolExecutor. Из javadocs:

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

Для (2) похоже, что вы можете определить подкласс SwingWorker и создать новые экземпляры подкласса для каждой итерации вместо создания анонимного подкласса.

1 голос
/ 07 апреля 2010

Рассматривали ли вы использование простого таймера Java и ReadWriteLock , чтобы определить, выполняется ли задача при повторном срабатывании таймера? В этой ситуации вы можете просто выйти из этой конкретной итерации и ждать следующей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...