ScheduledThreadPoolExecutor之remove方法

之前用定时任务的线程池,设置了个任务,但是突然今天产品说,某些个操作需要中断某些任务(如果任务还没有执行),使其不能再到点执行了。于是查了API果然有这样一个方法。

ScheduledThreadPoolExecutor之remove方法

一看API,需要移除的是一个Runnable对象,想当然的就把任务调度的传入的Runable对象保留下来,然后进行删除。简要代码如下

Runnable:
    static class Task implements Runnable {

        @Override
        public void run() {
            System.out.println(Instant.now().getEpochSecond());
        }
    }
    public static void main(String[] args) {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(10);
        Task task = new Task();
        scheduledThreadPoolExecutor.schedule(new Task(), 10, TimeUnit.SECONDS);
        scheduledThreadPoolExecutor.remove(task);
        System.out.println(Instant.now().getEpochSecond());
    }

一执行,完蛋10s过后任务还是执行了,任务并没有移除

ScheduledThreadPoolExecutor之remove方法

看了下ScheduledThreadPoolExecutor中重写的 remove 方法是去他自己的 BlockingQueue 里面删除了一个任务,也就是这个方法 ScheduledThreadPoolExecutor.DelayedWorkQueue#remove ,这个的入参变成了 Object ,而且一看这个queue队列里面装的是 RunnableScheduledFuture 这个对象,这家伙肯定是实现了Runnable接口的,一看果然是,那么这个东西放到队列去的呢?

ScheduledThreadPoolExecutor之remove方法

再看 schedule 方法是返回了一个值的,猜想了下是不是封装过我们传入的Runbale对象,于是决定remove方法的返回值,结果一看返回的 ScheduledFuture 对象没有实现Runnable接口,而remove要的Runnable。有一点点坑的地方来了, RunnableScheduledFuture 这个是

ScheduledFuture这个的子类,面向接口编程嘛,最后是返回了一个父类接口,但是父类接口没有实现Runnable,子类才实现了。

ScheduledThreadPoolExecutor之remove方法

最后再看 ScheduledThreadPoolExecutor#delayedExecute 这个方法里面刚好把刚才的那个RunnableScheduledFuture对象传入进去了并且加入到队列中去了。这样就和前面联系起来了

ScheduledThreadPoolExecutor之remove方法

如此一来 我们只需要把schedule方法的返回值强转成子类对象RunnableScheduledFuture,保存下来,然后再去调用remove应该可以成功的移除了

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(10);
        Task task = new Task();
        RunnableScheduledFuture<?> schedule =
                (RunnableScheduledFuture<?>) scheduledThreadPoolExecutor.schedule(task, 10, TimeUnit.SECONDS);
        scheduledThreadPoolExecutor.remove(schedule);
        System.out.println(Instant.now().getEpochSecond());


    }

虽然有API供参考,但是就像前面只看API的时候,那个Runnable参数到底该什么,还得要去看下ScheduledThreadPoolExecutor中别人是怎么实现的才能知道。

原文 

http://www.cnblogs.com/nijunyang/p/12657039.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » ScheduledThreadPoolExecutor之remove方法

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址