2013-07-23 7 views
3

У меня есть TimerTask, который предназначен для сбора показателей за определенный интервал. Однако возможно, что период выполнения задачи меньше времени выполнения задачи (иногда, если что-то истекает и задерживается).Параллельное выполнение запланированных задач в Java

Есть ли способ выполнить несколько TimerTasks или Runnables, потоков и т. Д. Одновременно, не дожидаясь завершения предыдущей задачи?

Я знаю, что таймер использует одну нить, а ScheduledThreadPoolExecutor задерживает выполнение независимо от скорости.

Спасибо.

+0

Так вы можете объяснить более конкретное, почему «ScheduledThreadPoolExecutor.scheduleAtFixedRate (..)' не подходит для ваших нужд? – Desert

+2

В соответствии с API и из моих тестов, используя его ... _ «Если какое-либо выполнение этой задачи занимает больше времени, чем ее период, последующие исполнения могут начинаться с опозданием, но не будут выполняться одновременно». _ Из [Java API] (http : //docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html) – 0G0

ответ

2

Я бы порекомендовал вам использовать Executors.newCachedThreadPool() или newCachedThreadPool(ThreadFactory threadFactory) с вашей собственной фабрикой ниток, в сочетании с таймером. Таким образом, код должен выглядеть следующим образом

Executor executor = Executors.newCachedThreadPool(); 
Timer time = new Timer(); 
timer.scheduleAtFixedRate(new TimerTask() { 

    public void run() { 
     executor.execute(new Runnable() { 

      public void run() { 
        //your business logic 
      } 
     }); 
    } 
}, delay, period); 

Таким образом, вы бы планировать задачи с какой-то период, и все они будут работать одновременно.

+0

Это получилось ... Спасибо! Если бы кто-то мог объяснить, как это работает, в отличие от метода Timer или метода Scheduler, я был бы признателен за знание. По сути, как это происходит вокруг блокировки. – 0G0

+0

Причина в том, что таймер имеет свой собственный поток, и единственное, что делает этот поток, это отправка задач на «CachedThreadPool», которые затем запускают почти каждую новую задачу в отдельном потоке. Надеюсь, я быстро разобрался :) Вы можете спросить больше, если вы что-то не поняли – Desert

+0

Ок, очевидно, это не сработало ... Я понятия не имею, что происходит ... Я использовал код выше, и кажется, что если поток B заканчивается перед потоком A, тогда таймер «догоняет» и быстро запускает другие потоки. Я посмотрел на метку времени на моих сточных машинах, и у меня было 14 объектов с одинаковой меткой времени. На данный момент я в недоумении. – 0G0

0

Используйте любую реализацию таймера, в том числе ScheduledThreadPoolExecutor, но пусть ваша задача таймера не выполняет вашу бизнес-логику, а вместо этого быстро запустит другую задачу (в пул кешированных потоков или собственный вновь созданный поток), который фактически выполняет тяжелые вычисления ,

Смежные вопросы