В настоящее время я пытаюсь разработать свой собственный таймер на 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<?>
экземпляров.
Есть ли способ определить, сколько раз запустить, или создать надежныйсистема, которая отменяет событие без потери точности?