Cyclical and major source parsing thread pool

Before learning to use ThreadPool and source code analysis, and from the perspective of the interview to answer introduce knowledge points. Today Xiaoqiang brought periodically use the thread pool and the focus of source code analysis.

ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor: tasks to processing delays or timing Task
class configuration diagram of the timing of the thread pool
FIG timing of the thread pool class structure of the class

ScheduledThreadPoolExecutor receiving ScheduleFutureTask type of task, the thread pool is the smallest unit of scheduling tasks.
It uses DelayQueue stored waiting tasks:
1, inside a package into DelayQueue PriorityQueue, it has according to the chronological order of time, if the same time sorting eradicate sequenceNumber;
2, DelayQueue is unbounded queue;

Periodic task execution thread pool sketch

ScheduleFutureTask

Received parameters:

private final long sequenceNumber;//任务的序号
private long time;//任务开始的时间
private final long period;//任务执行的时间间隔

During the execution of worker threads: the
worker thread will be removed from the DelayQueue to perform tasks that have expired;
re-set the expiration time for the task after the execution, DelayQueue back again;

ScheduledThreadPoolExecutor task will be performed into the work queue DelayQueue, DelayQueue encapsulates a PriorityQueue, PriorityQueue ScheduledFutureTask will queue sorting, sorting algorithms specifically implemented as follows:

public int compareTo(Delayed other) {
    if (other == this) // compare zero if same object
        return 0;
    if (other instanceof ScheduledFutureTask) {
        ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
        //首先按照time排序,time小的排到前面,time大的排到后面
        long diff = time - x.time;
        if (diff < 0)
            return -1;
        else if (diff > 0)
            return 1;
        //time相同,按照sequenceNumber排序;
        //sequenceNumber小的排在前面,sequenceNumber大的排在后面 
        else if (sequenceNumber < x.sequenceNumber)
            return -1;
        else
            return 1;
    }
    long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
    return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}

Then take a look ScheduledFutureTask run method to achieve, run method is the core task of scheduling, task execution is actually execute the run method.

public void run() {
    //是否是周期性的
    boolean periodic = isPeriodic();
    //线程池是shundown状态不支持处理新任务,直接取消任务
    if (!canRunInCurrentRunState(periodic))
        cancel(false);
    //如果不需要执行执行周期性任务,直接执行run方法结束
    else if (!periodic)
        ScheduledFutureTask.super.run();
    //如果需要周期性执行,则在执行任务完成后,设置下一次执行时间
    else if (ScheduledFutureTask.super.runAndReset()) {
        //设置下一次执行该任务的时间
        setNextRunTime();
        //重复执行该任务
        reExecutePeriodic(outerTask);
    }
}

Run method step:

  • 1, if the thread pool is shundown state does not support the deal with new tasks, directly cancel the task, otherwise step 2;
  • 2, if the task is not cyclical, direct call ScheduledFutureTask the run method executes, it sets the results, then returned directly, or else step 3;
  • 3, if a periodic task, the call ScheduledFutureTask runAndset method performed, the execution result is not set, then returned directly, otherwise step 4 and step 5;
  • 4, the calculated first execution time of the task;
  • 5 is repeatedly performed the task;

Next, look reExecutePeriodic method step:

void reExecutePeriodic(RunnableScheduledFuture<?> task) {
    if (canRunInCurrentRunState(true)) {
        super.getQueue().add(task);
        if (!canRunInCurrentRunState(true) && remove(task))
            task.cancel(false);
        else
            ensurePrestart();
    }
}

Having performed a periodic task, so it will not reject the current task, passing the task must be a periodic task.

Periodic thread pool task submission

There are three ways periodic submission: schedule, sceduleAtFixedRate, schedlueWithFixedDelay. The following is described from the use and source two areas, first, if you submit tasks:

pool.schedule(new Runnable() {
    @Override
    public void run() {
        System.out.println("延迟执行");
    }
},1, TimeUnit.SECONDS);

/**
 * 这个执行周期是固定,不管任务执行多长时间,每过3秒中就会产生一个新的任务
 */
pool.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        //这个业务逻辑需要很长的时间,超过了3秒
        System.out.println("重复执行");
    }
},1,3,TimeUnit.SECONDS);

pool.shutdown();

/**
 * 假如run方法30min后执行完成,然后间隔3秒,再周期性执行下一个任务
 */
pool.scheduleWithFixedDelay(new Runnable() {
    @Override
    public void run() {
        //30min
        System.out.println("重复执行");
    }
},1,3,TimeUnit.SECONDS);

Know how to submit periodic tasks, the next source is how to implement it, first schedule method, which refers to the task after a specified delay time reaches the trigger, only once.

public ScheduledFuture<?> schedule(Runnable command,
                                   long delay,
                                   TimeUnit unit) {
    if (command == null || unit == null)
        throw new NullPointerException();
    //把任务封装成ScheduledFutureTask,之后调用decorateTask进行包装;
    //decorateTask方法是空方法,留给用户去实现的;
    RunnableScheduledFuture<?> t = decorateTask(command,
        new ScheduledFutureTask<Void>(command, null,
                                      triggerTime(delay, unit)));
    //包装好任务之后,进行任务的提交                                  
    delayedExecute(t);
    return t;
}

Job submission method:

private void delayedExecute(RunnableScheduledFuture<?> task) {
    //如果线程池不是RUNNING状态,则使用拒绝策略把提交任务拒绝掉
    if (isShutdown())
        reject(task);
    else {
        //与ThreadPoolExecutor不同,这里直接把任务加入延迟队列
        super.getQueue().add(task);
        //如果当前状态无法执行任务,则取消
        if (isShutdown() &&
            !canRunInCurrentRunState(task.isPeriodic()) &&
            remove(task))
            task.cancel(false);
        else
        //和ThreadPoolExecutor不一样,corePoolSize没有达到会增加Worker;
        //增加Worker,确保提交的任务能够被执行
            ensurePrestart();
    }
}

I'm not concerned about the number of the public?

  • Sweep end the two-dimensional code number [of public concern Xiaoqiang advanced road] can receive as follows:
  • Learning materials: 1T Video Tutorial: front and rear end covers Javaweb instructional videos, machine learning / AI instructional videos, Linux system tutorial videos, IELTS video tutorials;
  • More than 100 books: containing C / C ++, Java, Python programming language must see three books, LeetCode explanations Daquan;
  • Software tools: Most software includes almost you might use in programming the road;
  • Project Source: 20 JavaWeb source projects.
    Advanced small strong way two-dimensional code

Guess you like

Origin www.cnblogs.com/xiaoqiang-code/p/11432936.html