今日学习(自律天数:13) 定期线程池源码阅读 + 简历项目优化 + 力扣

137 阅读1分钟

前言

进入阅读了一下定期线程池源码,感觉还是不错的。简历就是把前2天的项目给封装到简历上去了。

1.ScheduledExecutorService

首先看他的2个核心方法


public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,  long initialDelay,  long delay,  TimeUnit unit);

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,  long initialDelay,  long period,  TimeUnit unit);

//4个参数 command任务  initialDelay第一次执行需要延时嘛  period每个任务的延时时间 
//`scheduleAtFixedRate` 方法:该方法按照固定的时间间隔执行任务,无论上一次任务是否完成。
//`scheduleWithFixedDelay` 方法:该方法在上一次任务完成后,等待固定的时间间隔后再执行下一次任务。

源码阅读 scheduleWithFixedDelay方法


public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,  long initialDelay,  
long delay,  TimeUnit unit) {  
//参数校验
if (command == null || unit == null)  
    throw new NullPointerException();  
if (delay <= 0)  
    throw new IllegalArgumentException();  
 //封装任务
ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(command,  
null,  triggerTime(initialDelay, unit),  unit.toNanos(-delay));  
//这个方法目前没看出有什么用..
RunnableScheduledFuture<Void> t = decorateTask(command, sft);  

sft.outerTask = t;  
//关键追进去
delayedExecute(t);  
return t;  
}

delayedExecute方法

    private void delayedExecute(RunnableScheduledFuture<?> task) {  
        //判断线程池状态是否关闭
        if (isShutdown())  
        //拒绝策略
        reject(task);  
        else {  
            //当前任务入队
            super.getQueue().add(task);  
            //判断线程池状态
        if (isShutdown() &&  
            !canRunInCurrentRunState(task.isPeriodic()) &&  
            remove(task))  
            task.cancel(false);  
         else  
            //关键
            ensurePrestart();  
}  
}
void ensurePrestart() {  
//这个之前说过了 拿到工作线程数量
int wc = workerCountOf(ctl.get());
//看是否超过核心线程
if (wc < corePoolSize)
//创建一个工作线程
addWorker(null, true);  
else if (wc == 0)  
//创建一个工作线程
addWorker(null, false);  
}

addWorker方法没什么好看的吧 他不是加入队列了吗就看Worker队列拿出来之后干了什么就知道了呗ScheduledFutureTask的run方法就行今天就这把后面具体代码不是很懂啊