/** * Executes one instance of the task, or queues it up at most once should the task be currently running. */ void runAsync() { // Determine if a task is running. If so, record the fact we want to have it run again, otherwise reserve our spot. synchronized (this) { Exceptions.checkNotClosed(this.closed, this); if (this.running) { this.runAgain = true; return; } this.running = true; } // Execute the task. runInternal(); }
private void runInternal() { this.retry.runInExecutor(this.runnable, this.executor) .whenComplete((r, ex) -> { if (ex != null) { // If we were unable to execute after all retries, invoke the failure callback. Callbacks.invokeSafely(this.failureCallback, ex, null); } boolean loopAgain; synchronized (this) { this.running = this.runAgain && !this.closed; this.runAgain = false; loopAgain = this.running; } if (loopAgain) { runInternal(); } }); }