当然我们也可以使用工具类Executors的newScheduledThreadPool的方法 , 快速创建 。注意这里使用的DelayedWorkQueue 。
ScheduledThreadPoolExecutor没有提供带有最大线程数的构造函数的 , 默认是Integer.MAX_VALUE , 说明其可以无限制的开启任意线程执行任务 , 在大量任务系统 , 应注意这一点 , 避免内存溢出 。
核心方法核心方法主要介绍ScheduledThreadPoolExecutor的调度方法 , 其他方法与 ThreadPoolExecutor 一致 。调度方法均由 ScheduledExecutorService 接口定义:
public interface ScheduledExecutorService extends ExecutorService { // 特定时间延时后执行一次Runnable public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); // 特定时间延时后执行一次Callable public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); // 固定周期执行任务(与任务执行时间无关 , 周期是固定的) public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); // 固定延时执行任务(与任务执行时间有关 , 延时从上一次任务完成后开始) public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);}我们再来看一下接口的实现 , 具体是怎么来实现线程池任务的提交 。因为最终都回调用 delayedExecute 提交任务 。所以 , 我们这里只分析schedule方法 , 该方法是指任务在指定延迟时间到达后触发 , 只会执行一次 。源代码如下:
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { //参数校验 if (command == null || unit == null) throw new NullPointerException(); //这里是一个嵌套结构 , 首先把用户提交的任务包装成ScheduledFutureTask //然后在调用decorateTask进行包装 , 该方法是留给用户去扩展的 , 默认是个空方法 RunnableScheduledFuture<?> t = decorateTask(command, new ScheduledFutureTask<Void>(command, null, triggerTime(delay, unit))); //包装好任务以后 , 就进行提交了 delayedExecute(t); return t;}
推荐阅读
- 富春山居图是中国十大传名画之一这幅画的作者是 富春山居图是中国十大传世名画之一这幅画的作者是什么
- 古代寒门科举之路 没有科举之前都怎么当官的
- 班盆之美可比之班章,大滇号701批六星贺开
- 张仪得五寸退二寸之谋 张仪三寸不烂之舌纵横六国
- 英雄无用武之地的意思解释 形容英雄无用武之地的词语
- 绿茶之采花毛尖,采花毛尖价格预测
- 武则天在位多少年怎么退位的 武则天退位之后还活了多久
- |当了领导之后才明白的三个道理
- 胎儿男女双顶径对照表
- 康熙用人之术 康熙的用人之道
