一旦我认为它已经完成,如何在ScheduledThreadPoolExecutor中停止任务

我有一个ScheduledThreadPoolExecutor,我用它来安排一个以固定速率运行的任务。 我希望任务以指定的延迟运行最多10次,直到它“成功”。 在那之后,我不希望重试任务。 所以基本上我需要停止运行计划任务,当我希望它被停止时,但不关闭ScheduledThreadPoolExecutor。 知道我是怎么做的吗?

这是一些伪代码 –

public class ScheduledThreadPoolExecutorTest { public static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(15); // no multiple instances, just one to serve all requests class MyTask implements Runnable { private int MAX_ATTEMPTS = 10; public void run() { if(++attempt <= MAX_ATTEMPTS) { doX(); if(doXSucceeded) { //stop retrying the task anymore } } else { //couldn't succeed in MAX attempts, don't bother retrying anymore! } } } public void main(String[] args) { executor.scheduleAtFixedRate(new ScheduledThreadPoolExecutorTest().new MyTask(), 0, 5, TimeUnit.SECONDS); } } 

运行此测试,它打印1 2 3 4 5并停止

 public class ScheduledThreadPoolExecutorTest { static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(15); // no static ScheduledFuture t; static class MyTask implements Runnable { private int attempt = 1; public void run() { System.out.print(attempt + " "); if (++attempt > 5) { t.cancel(false); } } } public static void main(String[] args) { t = executor.scheduleAtFixedRate(new MyTask(), 0, 1, TimeUnit.SECONDS); } } 

在线程之外很好地取消了:

 public class ScheduleTest { @Test public void testCancel() throws Exception { final ScheduledThreadPoolExecutor EXECUTOR = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2); ScheduledFuture f1 = EXECUTOR.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("Im alive 1"); } }, 0, 1, TimeUnit.SECONDS); ScheduledFuture f2 = EXECUTOR.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("Im alive 2"); } }, 0, 2, TimeUnit.SECONDS); Thread.sleep(10000); f1.cancel(true); System.out.println("f1 cancel"); Thread.sleep(10000); f2.cancel(false); System.out.println("f2 cancel"); Thread.sleep(10000); } } 

有时线程无法取消,这通常通过volatile boolean isCancelled;解决volatile boolean isCancelled;

CountDownLatch是一种替代方法。 线程完成后,在锁存器上调用countDown() 。 调用线程调用latch.await()直到所有线程完成。 此时调用ExecutorService.shutdownNow()以便您的主线程不会变成僵尸。

 import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPoolExecutorTest { static int i = 0; public static void main(String[] args) throws Exception { final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); final CountDownLatch latch = new CountDownLatch(1); executor.scheduleAtFixedRate(() -> { System.out.println(++i); if (i > 4) { latch.countDown(); } }, 0, 100, TimeUnit.MILLISECONDS); latch.await(); executor.shutdownNow(); } }