取消在 ScheduledExecutorService 中安排的任务可使执行程序保持活动状态
Cancelling a task scheduled in a ScheduledExecutorService keeps executor alive
这已经困扰我几个小时了。如果我安排一个任务在 5 秒内执行 然后立即取消该任务,我希望 "awaitTermination" 方法立即 return,但它会一直阻塞 7 秒 (不是五秒)..
这是重现 Java11 上的问题的 JUnit 5 测试用例。
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");
}
}
有什么想法吗?
您不在 executorService 上调用 shutdown 或 shutdownNow,因此您可以永远等待。它永远不会终止。先调用关闭,然后单元测试应该工作。
scheduled.cancel(false);
executorService.shutdown(); // This was missing
if (!executorService.awaitTermination(7, TimeUnit.SECONDS)) {
...
awaitTermination "Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first"(从评论中复制,感谢 ptomli)。
这已经困扰我几个小时了。如果我安排一个任务在 5 秒内执行 然后立即取消该任务,我希望 "awaitTermination" 方法立即 return,但它会一直阻塞 7 秒 (不是五秒)..
这是重现 Java11 上的问题的 JUnit 5 测试用例。
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");
}
}
有什么想法吗?
您不在 executorService 上调用 shutdown 或 shutdownNow,因此您可以永远等待。它永远不会终止。先调用关闭,然后单元测试应该工作。
scheduled.cancel(false);
executorService.shutdown(); // This was missing
if (!executorService.awaitTermination(7, TimeUnit.SECONDS)) {
...
awaitTermination "Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first"(从评论中复制,感谢 ptomli)。