本文分享自华为云社区《【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例》,作者:冰河。 JDK1。5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能。在JDK1。5之前,实现任务的周期性调度主要使用的是Timer类和TimerTask类。本文,就简单介绍下ScheduledThreadPoolExecutor类与Timer类的区别,ScheduledThreadPoolExecutor类相比于Timer类来说,究竟有哪些优势,以及二者分别实现任务调度的简单示例。二者的区别线程角度Timer是单线程模式,如果某个TimerTask任务的执行时间比较久,会影响到其他任务的调度执行。ScheduledThreadPoolExecutor是多线程模式,并且重用线程池,某个ScheduledFutureTask任务执行的时间比较久,不会影响到其他任务的调度执行。系统时间敏感度Timer调度是基于操作系统的绝对时间的,对操作系统的时间敏感,一旦操作系统的时间改变,则Timer的调度不再精确。ScheduledThreadPoolExecutor调度是基于相对时间的,不受操作系统时间改变的影响。是否捕获异常Timer不会捕获TimerTask抛出的异常,加上Timer又是单线程的。一旦某个调度任务出现异常,则整个线程就会终止,其他需要调度的任务也不再执行。ScheduledThreadPoolExecutor基于线程池来实现调度功能,某个任务抛出异常后,其他任务仍能正常执行。任务是否具备优先级Timer中执行的TimerTask任务整体上没有优先级的概念,只是按照系统的绝对时间来执行任务。ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类实现了java。lang。Comparable接口和java。util。concurrent。Delayed接口,这也就说明了ScheduledFutureTask类中实现了两个非常重要的方法,一个是java。lang。Comparable接口的compareTo方法,一个是java。util。concurrent。Delayed接口的getDelay方法。在ScheduledFutureTask类中compareTo方法方法实现了任务的比较,距离下次执行的时间间隔短的任务会排在前面,也就是说,距离下次执行的时间间隔短的任务的优先级比较高。而getDelay方法则能够返回距离下次任务执行的时间间隔。是否支持对任务排序Timer不支持对任务的排序。ScheduledThreadPoolExecutor类中定义了一个静态内部类DelayedWorkQueue,DelayedWorkQueue类本质上是一个有序队列,为需要调度的每个任务按照距离下次执行时间间隔的大小来排序能否获取返回的结果Timer中执行的TimerTask类只是实现了java。lang。Runnable接口,无法从TimerTask中获取返回的结果。ScheduledThreadPoolExecutor中执行的ScheduledFutureTask类继承了FutureTask类,能够通过Future来获取返回的结果。 通过以上对ScheduledThreadPoolExecutor类和Timer类的分析对比,相信在JDK1。5之后,就没有使用Timer来实现定时任务调度的必要了。二者简单的示例 这里,给出使用Timer和ScheduledThreadPoolExecutor实现定时调度的简单示例,为了简便,我这里就直接使用匿名内部类的形式来提交任务。Timer类简单示例 源代码示例如下所示。packageio。binghe。concurrent。lab09;importjava。util。Timportjava。util。TimerTauthorbingheversion1。0。0description测试TimerpublicclassTimerTest{publicstaticvoidmain(String〔〕args)throwsInterruptedException{TimertimernewTimer();timer。scheduleAtFixedRate(newTimerTask(){Overridepublicvoidrun(){System。out。println(测试Timer类);}},1000,1000);Thread。sleep(10000);timer。cancel();}} 运行结果如下所示。测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类测试Timer类ScheduledThreadPoolExecutor类简单示例 源代码示例如下所示。packageio。binghe。concurrent。lab09;importjava。util。concurrent。;authorbingheversion1。0。0description测试ScheduledThreadPoolExecutorpublicclassScheduledThreadPoolExecutorTest{publicstaticvoidmain(String〔〕args)throwsInterruptedException{ScheduledExecutorServicescheduledExecutorServiceExecutors。newScheduledThreadPool(3);scheduledExecutorService。scheduleAtFixedRate(newRunnable(){Overridepublicvoidrun(){System。out。println(测试测试ScheduledThreadPoolExecutor);}},1,1,TimeUnit。SECONDS);主线程休眠10秒Thread。sleep(10000);System。out。println(正在关闭线程池。。。);关闭线程池scheduledExecutorService。shutdown();booleanisC等待线程池终止do{isClosedscheduledExecutorService。awaitTermination(1,TimeUnit。DAYS);System。out。println(正在等待线程池中的任务执行完成);}while(!isClosed);System。out。println(所有线程执行结束,线程池关闭);}} 运行结果如下所示。测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor测试测试ScheduledThreadPoolExecutor正在关闭线程池。。。测试测试ScheduledThreadPoolExecutor正在等待线程池中的任务执行完成所有线程执行结束,线程池关闭 注意:关于Timer和ScheduledThreadPoolExecutor还有其他的使用方法,这里,我就简单列出以上两个使用示例,更多的使用方法大家可以自行实现。