ScheduledFutureTask

321 阅读1分钟

1 类继承关系

image.png

2 代码详情

ScheduledFutureTask

类签名

final class ScheduledFutureTask extends PromiseTask implements ScheduledFuture, PriorityQueueNode

包可见性,所以这个类只能netty内部使用,不往外暴露

继承了PromiseTask

实现了ScheduledFuture, PriorityQueueNode,表明是用来实现了定时任务用的, 是定时任务实现中,优先级队列里面的元素的类型

字段

id

  • private long id;
    
  • set once when added to priority queue

deadlineNanos

  • private long deadlineNanos;
    
  • 用纳秒表示的Runnable要执行的时间

periodNanos

  • private final long periodNanos;
    
  • =0,表示不重复, > 0表示以固定的频率重复,<0,表示以固定的延时重复

queueIndex

  • private int queueIndex
  • 表示在队里中的位置

共有方法

public long getDelay(TimeUnit unit)

  • 返回还有多少时间就要开始执行
  • 用this.deadlineNanos - 当前的纳秒数

public int compareTo(Delayed o)

  • 先比较this.deadlineNanos,如果执行时间相同就比较id
  • 早执行的,id小的,小

public void run()

  • 1 做断言,父类DefaultPromise的EventExecutor变量,必须在EventLoop里面

    • assert executor().inEventLoop();
  • 2 如果还没有到执行时间,则如果任务已经被取消,则从优先级队里中删除,否则加入到优先级队列中,return

      if (delayNanos() > 0L) {
              // Not yet expired, need to add or remove from queue
              if (isCancelled()) {
                  scheduledExecutor().scheduledTaskQueue().removeTyped(this);
              } else {
                  scheduledExecutor().scheduleFromEventLoop(this);
              }
              return;
          }
    
  • 3 如果不是周期任务,则将其当成PromiseFuture处理

         if (setUncancellableInternal()) {
                  V result = runTask();
                  setSuccessInternal(result);
              }
    
    • 如果能设置能DefaultPromise.result设置成不可取消的,就执行runTask()方法,然后将运行结果设置到result中,然后将task赋值为COMPLETED
  • 4 否则则是周期任务了,那么判断是否已经被取消,如果没有被取消则

    • runTask()

    • 如果父类DefaultPromise的EventExecutor变量,没有关闭则,根据this.periodNanos去更改执行时间this.deadlineNanos,然后将其再次加入到优先级队列中

          if (!executor().isShutdown()) {
                    if (periodNanos > 0) {
                        deadlineNanos += periodNanos;
                    } else {
                        deadlineNanos = nanoTime() - periodNanos;
                    }
                    if (!isCancelled()) {
                        scheduledExecutor().scheduledTaskQueue().add(this);
                    }
                }
      
  • 会捕获以上四部的异常

    • 将PromiseTask的setFailureInternal方法,将result设置为异常,并且将task赋值为FAILED

public boolean cancel(boolean mayInterruptIfRunning)

  • 这个方法是覆盖PromiseTask的取消函数,在那个逻辑的基础上在加入从优先级队列中删除的逻辑

      boolean canceled = super.cancel(mayInterruptIfRunning);
      if (canceled) {
          scheduledExecutor().removeScheduled(this);
      }
      return canceled;