赞
踩
作者:刘宇
CSDN博客地址:https://blog.csdn.net/liuyu973971883
有部分资料参考,如有侵权,请联系删除。如有不正确的地方,烦请指正,谢谢。
ScheduledExecutorService是基于ExecutorService的功能实现的延迟和周期执行任务的功能。每个任务以及每个任务的每个周期都会提交到线程池中由线程去执行,所以任务在不同周期内执行它的线程可能是不同的。ScheduledExecutorService接口的默认实现类是ScheduledThreadPoolExecutor。在周期执行的任务中,如果任务执行时间大于周期时间,则会以任务时间优先,等任务执行完毕后才会进入下一次周期
因为ScheduledThreadPoolExecutor继承了ThreadPoolExecutor类,所以有很多方法都是来自ThreadPoolExecutor类的,这里就不做解释了,想了解的兄弟可以看我前面的博客:点击查看详细
构造一个Schedule线程池,最大线程数为Integer的最大值,线程的空闲时间为0,队列采用的是DelayedWorkQueue
ScheduledThreadPoolExecutor(int corePoolSize)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)
ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)
延时执行runnable或者callable任务。执行runnable任务时是没有结果返回的,那为什么还会返回ScheduledFuture,因为我们可以通过Future做一些取消任务等操作。
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
固定周期性执行任务,当任务的执行时长大于周期,那么下一个周期任务将在上一个执行完毕之后马上执行。
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
固定延时执行任务,也是周期性任务,和scheduleAtFixedRate不同的是:scheduleAtFixedRate当任务执行时间小于周期时间时,此时周期时间到了的时候会进入下一周期,如果任务执行时间大于周期时间时,任务结束后会立即进入下一周期;而scheduleWithFixedDelay是无论你任务时间是否超过,都将会在你任务执行完毕后延迟固定秒数,才会进入下一周期。
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
默认为false。在线程池执行shutdown方法后是否继续执行scheduleAtFixedRate方法和scheduleWithFixedDelay方法提交的任务
void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value)
默认为true,在线程池执行shutdown方法后,需要等待当前正在等待的任务的和正在运行的任务被执行完,然后进程被销毁。为false时,表示放弃等待的任务,正在运行的任务一旦完成,则进程被销毁。
void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value)
本次练习中出来schedule的练习外,还包含了如何取消任务。
package com.brycen.part3.threadpool; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ScheduledExecutorServiceExample { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2); //2秒后执行runnable任务 scheduledThreadPoolExecutor.schedule(() -> { System.out.println("This is runable1 task"); }, 2, TimeUnit.SECONDS); //提交一个2秒后才执行的runnable任务 //既然runnable无法返回结果,为什么还要有Future呢,因为我们可以通过Future进行取消任务等操作 ScheduledFuture<?> runnableFuture = scheduledThreadPoolExecutor.schedule(() -> { System.out.println("This is runable2 task"); }, 2, TimeUnit.SECONDS); //取消任务 runnableFuture.cancel(true); //休眠3秒,确保上面的任务都被执行完 mySleep(3); System.out.println("========================"); } private static void mySleep(int seconds){ try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
This is runable1 task
========================
周期性执行某个任务,执行到一定之间后取消任务
package com.test.part3.threadpool; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ScheduledExecutorServiceExample2 { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2); //提交延迟1秒执行,周期为2秒的runnable任务,虽然runnable没有返回结果,但是可以通过runnable取消任务 ScheduledFuture<?> runnableFuture = scheduledThreadPoolExecutor.scheduleAtFixedRate(() -> { System.out.println("This is runable task running "+Thread.currentThread().getName()); }, 1,2, TimeUnit.SECONDS); //休眠8秒 mySleep(8); //取消该循坏任务 runnableFuture.cancel(true); } private static void mySleep(int seconds){ try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
This is runable task running pool-1-thread-1
This is runable task running pool-1-thread-1
This is runable task running pool-1-thread-1
This is runable task running pool-1-thread-2
超时的周期性任务
package com.brycen.part3.threadpool; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class ScheduledExecutorServiceExample3 { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2); AtomicLong atomicLong = new AtomicLong(0L); //提交初始延迟1秒执行,固定周期为2秒的runnable任务 ScheduledFuture<?> runnableFuture = scheduledThreadPoolExecutor.scheduleAtFixedRate(() -> { //记录当前时间 Long current = System.currentTimeMillis(); //判断是否为第一次运行 if (atomicLong.get()==0){ atomicLong.set(current); System.out.printf("first running [%d]\n",atomicLong.get()); }else{ //记录与上次的间隔时间 System.out.printf("running time:[%d]\n",current-atomicLong.get()); } //将当前时间保存 atomicLong.set(current); //模拟超过固定周期时间 mySleep(5); }, 1,2, TimeUnit.SECONDS); } private static void mySleep(int seconds){ try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
first running [1597659726690]
running time:[5042]
running time:[5001]
running time:[5000]
running time:[5001]
package com.test.part3.threadpool; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class ScheduledExecutorServiceExample4 { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2); AtomicLong atomicLong = new AtomicLong(0L); //提交初始延迟1秒执行,延迟为2秒的runnable任务 ScheduledFuture<?> runnableFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> { //记录当前时间 Long current = System.currentTimeMillis(); //判断是否为第一次运行 if (atomicLong.get()==0){ atomicLong.set(current); System.out.printf("first running [%d]\n",atomicLong.get()); }else{ //记录与上次的间隔时间 System.out.printf("running time:[%d]\n",current-atomicLong.get()); } //将当前时间保存 atomicLong.set(current); //模拟超过固定周期时间 mySleep(5); }, 1,2, TimeUnit.SECONDS); } private static void mySleep(int seconds){ try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
first running [1597659862349]
running time:[7047]
running time:[7002]
running time:[7023]
running time:[7002]
running time:[7003]
package com.brycen.concurrency03.threadpool; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ScheduledExecutorServiceExample5 { public static void main(String[] args) { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2); //提交固定周期任务 ScheduledFuture<?> runnableFuture = scheduledThreadPoolExecutor.scheduleAtFixedRate(() -> { System.out.println("This is runable task running "+Thread.currentThread().getName()); }, 1,2, TimeUnit.SECONDS); //默认情况关闭线程池后是不允许继续执行固定周期任务的,所有输出false System.out.println(scheduledThreadPoolExecutor.getContinueExistingPeriodicTasksAfterShutdownPolicy()); //设置为true scheduledThreadPoolExecutor.setContinueExistingPeriodicTasksAfterShutdownPolicy(true); //休眠1200毫秒,确保任务被执行 mySleep(1200); //关闭线程池 scheduledThreadPoolExecutor.shutdown(); //休眠2000毫秒后查看线程池状态 mySleep(2000); //线程池的状态 System.out.println("isShutdown:"+scheduledThreadPoolExecutor.isShutdown()); System.out.println("isTerminating:"+scheduledThreadPoolExecutor.isTerminating()); System.out.println("isTerminated:"+scheduledThreadPoolExecutor.isTerminated()); } private static void mySleep(int milliSeconds){ try { TimeUnit.MILLISECONDS.sleep(milliSeconds); } catch (InterruptedException e) { e.printStackTrace(); } } }
运行结果:
false
This is runable task running pool-1-thread-1
This is runable task running pool-1-thread-1
isShutdown:true
isTerminating:true
isTerminated:false
This is runable task running pool-1-thread-1
This is runable task running pool-1-thread-1
...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。