Отмена запланированной задачи в ScheduledExecutorService поддерживает выполнение исполнителя - PullRequest
1 голос
/ 12 марта 2019

Это вызывает у меня проблемы в течение нескольких часов. Если я запланирую выполнение задачи за 5 секунд , а затем немедленно откажусь от этой задачи, я буду ожидать, что метод "awaitTermination" немедленно вернется,но он блокируется в течение полных 7 секунд (не пять) ..

Вот тестовый пример JUnit 5, который воспроизводит проблему на Java 11.

package dummy;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;

class DummyTest {

  @Test
  @DisplayName("Cancelling task should work...")
  void cancel_task() throws InterruptedException {
    ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    AtomicBoolean isExecuted = new AtomicBoolean(false);
    ScheduledFuture<?> scheduled = executorService.schedule(() -> isExecuted.set(true), 5, TimeUnit.SECONDS);
    scheduled.cancel(false);

    if (!executorService.awaitTermination(7, TimeUnit.SECONDS)) {
      fail("Didn't shut down within timeout"); // <-- Fails here
    }

    assertFalse(isExecuted.get(), "Task should be cancelled before executed");
  }

}

Есть идеи?

1 Ответ

6 голосов
/ 12 марта 2019

Вы не вызываете shutdown или shutdownNow на вашем executorService, так что вы можете ждать вечно. Это никогда не закончится. Сначала вызовите отключение, затем должен работать модульный тест.

scheduled.cancel(false);
executorService.shutdown(); // This was missing
if (!executorService.awaitTermination(7, TimeUnit.SECONDS)) {
...

awaitTermination"Блокирует до тех пор, пока все задачи не завершат выполнение после запроса на завершение работы , или пока не истечет время ожидания, или текущий поток не прервется, в зависимости от того, что произойдет первым" (скопировано из комментариев, спасибо, птомли).

...