在【高并发专题】的专栏中 , 我们深度分析了ThreadPoolExecutor类的源代码,而ScheduledThreadPoolExecutor类是ThreadPoolExecutor类的子类 。今天我们就来一起手撕ScheduledThreadPoolExecutor类的源代码 。
构造方法我们先来看下ScheduledThreadPoolExecutor的构造方法,源代码如下所示 。
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());}public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue(), threadFactory);}public ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue(), handler);}public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue(), threadFactory, handler);}
从代码结构上来看,ScheduledThreadPoolExecutor类是ThreadPoolExecutor类的子类,ScheduledThreadPoolExecutor类的构造方法实际上调用的是ThreadPoolExecutor类的构造方法 。
schedule方法接下来,我们看一下ScheduledThreadPoolExecutor类的schedule方法,源代码如下所示 。
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { //如果传递的Runnable对象和TimeUnit时间单位为空 //抛出空指针异常 if (command == null || unit == null)throw new NullPointerException(); //封装任务对象,在decorateTask方法中直接返回ScheduledFutureTask对象 RunnableScheduledFuture<?> t = decorateTask(command, new ScheduledFutureTask<Void>(command, null, triggerTime(delay, unit))); //执行延时任务 delayedExecute(t); //返回任务 return t;}public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) //如果传递的Callable对象和TimeUnit时间单位为空 //抛出空指针异常 if (callable == null || unit == null)throw new NullPointerException(); //封装任务对象,在decorateTask方法中直接返回ScheduledFutureTask对象 RunnableScheduledFuture<V> t = decorateTask(callable,new ScheduledFutureTask<V>(callable, triggerTime(delay, unit))); //执行延时任务 delayedExecute(t); //返回任务 return t;}
从源代码可以看出 , ScheduledThreadPoolExecutor类提供了两个重载的schedule方法,两个schedule方法的第一个参数不同 。可以传递Runnable接口对象,也可以传递Callable接口对象 。在方法内部,会将Runnable接口对象和Callable接口对象封装成RunnableScheduledFuture对象,本质上就是封装成ScheduledFutureTask对象 。并通过delayedExecute方法来执行延时任务 。
在源代码中,我们看到两个schedule都调用了decorateTask方法,接下来,我们就看看decorateTask方法 。
decorateTask方法decorateTask方法源代码如下所示 。
protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) { return task;}protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) { return task;}
【【高并发】深度解析ScheduledThreadPoolExecutor类的源代码】通过源码可以看出decorateTask方法的实现比较简单,接收一个Runnable接口对象或者Callable接口对象和封装的RunnableScheduledFuture任务,两个方法都是将RunnableScheduledFuture任务直接返回 。在ScheduledThreadPoolExecutor类的子类中可以重写这两个方法 。
接下来,我们继续看下scheduleAtFixedRate方法 。
scheduleAtFixedRate方法scheduleAtFixedRate方法源代码如下所示 。
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { //传入的Runnable对象和TimeUnit为空,则抛出空指针异常 if (command == null || unit == null)throw new NullPointerException(); //如果执行周期period传入的数值小于或者等于0 //抛出非法参数异常 if (period <= 0)throw new IllegalArgumentException(); //将Runnable对象封装成ScheduledFutureTask任务, //并设置执行周期 ScheduledFutureTask<Void> sft =new ScheduledFutureTask<Void>(command, null, triggerTime(initialDelay, unit), unit.toNanos(period)); //调用decorateTask方法,本质上还是直接返回ScheduledFutureTask对象 RunnableScheduledFuture<Void> t = decorateTask(command, sft); //设置执行的任务 sft.outerTask = t; //执行延时任务 delayedExecute(t); //返回执行的任务 return t;}
通过源码可以看出,scheduleAtFixedRate方法将传递的Runnable对象封装成ScheduledFutureTask任务对象,并设置了执行周期,下一次的执行时间相对于上一次的执行时间来说 , 加上了period时长,时长的具体单位由TimeUnit决定 。采用固定的频率来执行定时任务 。
推荐阅读
- vivoy30手机的配置参数_vivoy30手机的配置怎么样
- 联发科g25处理器相当于骁龙多少_联发科g25处理器相当于骁龙什么处理器
- 穿越火线怎么用cf点改名(穿越火线修改昵称可以用cf点吗)
- 新版cf怎么改名(2022cf改名)
- 网上红心大战怎么玩(红心大战的玩法)
- 记一次 .NET 某娱乐聊天流平台 CPU 爆高分析
- 华为mate50发布时间确定_华为mate50官方首曝
- 艾诗缇的“黑科技”,到底有多强大?
- 三星手机如何截屏动图(三星s8截图怎么截长图)
- AI 【第1篇】人工智能语音测试原理和实践---宣传