I have a ScheduledThreadPoolExecutor with which I schedule a task to run at a fixed rate. I want the task to be running with a specified delay for a maximum of say 10 times
run this test, it prints 1 2 3 4 5
and stops
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);
}
}
Nicely cancelled outside of thread:
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);
}
}
Sometimes thread couldn't be cancelled, this solved usually via volatile boolean isCancelled;
CountDownLatch
is an alternative approach. When the thread completes, call countDown()
on the latch. The calling thread calls latch.await()
until all threads complete. At that point call ExecutorService.shutdownNow()
so that your main thread doesn't turn into a zombie.
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();
}
}