Запланируйте задание на запуск X раз каждые Y секунд - PullRequest
0 голосов
/ 18 сентября 2018

В настоящее время я пытаюсь разработать свой собственный таймер на Java.Однако проблема, которую я обнаружил, заключается в использовании ScheduledExecutorService для запуска задачи каждые несколько раз TimeUnit и выполнения Runnable X раз.В настоящее время у меня есть идея, однако, когда миллисекунды сокращаются, точность теряется.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class Timer {

    private static final ScheduledExecutorService SCHEDULER = Executors.newSingleThreadScheduledExecutor();
    private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor();

    private final Runnable action;
    private long initDelay;
    private long delay;

    public Timer(Runnable action, long delay) {
        this.action = action;
        this.delay = delay;
    }

    public Timer(Runnable action, long initDelay, long delay) {
        this.action = action;
        this.initDelay = initDelay;
        this.delay = delay;
    }

    public Future<?>[] runSynchronously(long count) throws InterruptedException {
        List<Future<?>> futures = new ArrayList<>();

        synchronized (SERVICE) {
            SERVICE.wait(initDelay);

            while (count > 0) {
                futures.add(SERVICE.submit(action));
                SERVICE.wait(delay);
                count--;
            }
        }

        return (Future<?>[]) futures.toArray();
    }

    public ScheduledFuture<?> runAsynchronously(long count) {
        ScheduledFuture future = SCHEDULER.scheduleWithFixedDelay(action, initDelay, delay, TimeUnit.MILLISECONDS);
        this.cancel(future, count);
        return future;
    }

    private void cancel(Future future, long count) {
        SCHEDULER.schedule(() -> future.cancel(true), initDelay + (delay * count), TimeUnit.MILLISECONDS);
    }

    private void cancel(ScheduledFuture future, long count) {
        SCHEDULER.schedule(() -> future.cancel(true), initDelay + (delay * count), TimeUnit.MILLISECONDS);
    }
}

В настоящее время, когда я использую это ...

final AtomicInteger atom = new AtomicInteger(0);

Timer timer = new Timer(() -> {
    atom.incrementAndGet();
    System.out.println(atom.get());
}, 1000, 1);

timer.runAsynchronously(10);

Счетчик достигнет 4. КогдаЯ ранее изменил задержку на 333, она могла бы произвести все числа.До этого я пытался создать цикл for, чтобы планировать его несколько раз, однако мне не нравилось накопление нескольких ScheduledFuture<?> экземпляров.

Есть ли способ определить, сколько раз запустить, или создать надежныйсистема, которая отменяет событие без потери точности?

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