美文网首页技术栈
2019-03-28——Java并发 Executor框架 Sc

2019-03-28——Java并发 Executor框架 Sc

作者: 烟雨乱平生 | 来源:发表于2019-03-28 23:53 被阅读0次

    ScheduledThreadPoolExecutor继承ThreadPoolExecutor来重用线程池的功能,它的实现方式如下:

    • 将任务封装成ScheduledFutureTask对象,ScheduledFutureTask基于相对时间,不受系统时间的改变所影响;
    • ScheduledFutureTask实现了java.lang.Comparable接口和java.util.concurrent.Delayed接口,所以有两个重要的方法:compareTo和getDelay。compareTo方法用于比较任务之间的优先级关系,如果距离下次执行的时间间隔较短,则优先级高;getDelay方法用于返回距离下次任务执行时间的时间间隔;
    • ScheduledThreadPoolExecutor定义了一个DelayedWorkQueue,它是一个有序队列,会通过每个任务按照距离下次执行时间间隔的大小来排序;
    • ScheduledFutureTask继承自FutureTask,可以通过返回Future对象来获取执行的结果。

    关于ScheduledThreadPoolExecutor的使用有三点需要说明如下:

    • ScheduledThreadPoolExecutor继承自ThreadPoolExecutor(,因而也有继承而来的execute()和submit()方法,但是ScheduledThreadPoolExecutor重写了这两个方法,重写的方式是直接创建两个立即执行并且只执行一次的任务;
    • ScheduledThreadPoolExecutor使用ScheduledFutureTask封装每个需要执行的任务,而任务都是放入DelayedWorkQueue队列中的,该队列是一个使用数组实现的优先队列,在调用ScheduledFutureTask::cancel()方法时,其会根据removeOnCancel变量的设置来确认是否需要将当前任务真正的从队列中移除,而不只是标识其为已删除状态;
    • ScheduledThreadPoolExecutor提供了一个钩子方法decorateTask(Runnable, RunnableScheduledFuture)用于对执行的任务进行装饰,该方法第一个参数是调用方传入的任务实例,第二个参数则是使用ScheduledFutureTask对用户传入任务实例进行封装之后的实例。这里需要注意的是,在ScheduledFutureTask对象中有一个heapIndex变量,该变量用于记录当前实例处于队列数组中的下标位置,该变量可以将诸如contains(),remove()等方法的时间复杂度从O(N)降低到O(logN),因而效率提升是比较高的,但是如果这里用户重写decorateTask()方法封装了队列中的任务实例,那么heapIndex的优化就不存在了,因而这里强烈建议是尽量不要重写该方法,或者重写时也还是复用ScheduledFutureTask类。

    相关文章

      网友评论

        本文标题:2019-03-28——Java并发 Executor框架 Sc

        本文链接:https://www.haomeiwen.com/subject/ilghbqtx.html