有条件地终止 ScheduledExecutorService 中运行的定时任务

编走编想 发布于 2013/07/25 17:27
阅读 29K+
收藏 1

Java 程序员都知道我们可以用 ScheduledExecutorService 按照一定的间隔或频率执行任务,但这个任务一旦开始,就只能到 ThreadPool shutdown 了才能结束。如何按照一定条件,在不终止整个线程池的情况下结束任务。

当然,有几个简单但不完美的解决方法,比如在任务中判断执行条件,但这样任务其实还会被线程池执行,只不过不做什么事情,这样是浪费资源的。再比如你自己写一个 ScheduledExecutorService 的实现,但又有点耗时耗力。

有什么方法可以兼顾简单和节省系统资源呢?

加载中
1
编走编想
编走编想

自己的问题自己回答

public class ConditionCancelScheduler {
    private static ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) throws Exception {
        final String jobID = "my_job_1";
        final AtomicInteger count = new AtomicInteger(0);
        final Map<String, Future> futures = new HashMap<>();

        final CountDownLatch countDownLatch = new CountDownLatch(1);
        Future future = scheduler.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                System.out.println(count.getAndIncrement());

                if (count.get() > 10) {
                    Future future = futures.get(jobID);
                    if (future != null) future.cancel(true);
                    countDownLatch.countDown();
                }
            }
        }, 0, 1, TimeUnit.SECONDS);

        futures.put(jobID, future);
        countDownLatch.await();

        scheduler.shutdown();
    }
}

0
m
mononite
使用返回的ScheduleFuture对象上的cancel方法;另外也一种选择是在run或者execute里根据条件抛异常。
m
mononite
Future怎么会不能直接cancel?看了一下你的代码,大概明白了,呵呵。 其实像这种根据条件来终止的周期任务,用schedule方法通常会比scheduleWithFixedXXX方法更合适。
编走编想
编走编想
Future 不能直接 cancel。我后来想了一下,用个 Map 就可以解决问题了
0
bloodkilory
bloodkilory
很好,解决了我的疑问
0
shalamy
shalamy

如果 run 里面写个while(true){System.out.println("dcxx")} 会发现这些即使你Cancel 任务之后,线程还是在运行的 ,这个是怎么回事????

编走编想
编走编想
因为你的任务不能响应线程中断,去看一下 thread interrupt 机制就懂了
返回顶部
顶部