咱们上篇文章分析了ThreadPoolExecutor,若是要用一句话说明它的主要优点,就是线程置换。还有Executors工具类,极大的简化了研发人员工做。java
我用一个图重复描述下线程池概念。多生产-多消费模型。面试
详细概念能够翻看我上一篇文章《线程池面试必考问题》。微信
还记得咱们上面说的阻塞队列吗?定时任务线程池底层使用DelayedQueue实现的,这种延迟队列有一个最大的特色:按时出队列,你们都考过驾照吧,科目三考试的时候都是车上坐的是4我的,假设一我的考试须要花15分钟,那么考试学员队列看起来是这样的。多线程
DelayedQueue底层须要实现Delayed接口同时须要实现getDelay方法和compareTo方法,getDelay方法用于计算出队列时间,一旦小于0就会出队列;compareTo方法用于按触发时间从小到大排序。这就是Schedule线程池任务延时原理,若是须要看案例代码,请参考我文章《并发队列:PriorityBlockingQueue和DelayQueue案例使用》。并发
由上图可知:假设线程任务:耗时1秒,定时3秒执行,scheduleWithFixedDelay实际上是4秒执行一次。ide
在ScheduledThreadPoolExecutor中,ScheduledFutureTask是获取定时任务返回值,继承FutureTask。咱们看下FutureTask调用get阻塞简化流程图。工具
在实际运用,咱们通常拿返回值测试多线程性能。性能
import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; /** * @author :jiaolian * @date :Created in 2021-02-25 13:50 * @description:Timer任务异常,Timer线程退出! * @modified By: * 公众号:叫练 */ public class TimerTaskExceptionTest { public static void main(String[] args) throws InterruptedException { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("first task"); } },0,1000); TimeUnit.SECONDS.sleep(3); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("second task"); int x = 5/0; } },0,1000); } }
如上代码:timer提交了first_task和second_task两个任务,3秒后,second_task执行5/0会抛出异常,此时timer线程会退出。若是换成ScheduledThreadPoolExecutor则不会影响first_task。在实际应用中,推荐用定时任务线程池中的方法去处理任务。测试
今天咱们介绍了线程池中面试中几个重要的面试点,整理出来但愿能对你有帮助,写的比不全,同时还有许多须要修正的地方,但愿亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是叫练【公众号】,微信号【jiaolian123abc】边叫边练。spa