美文网首页
java线程池 - ScheduledThreadPoolExe

java线程池 - ScheduledThreadPoolExe

作者: zbsong | 来源:发表于2020-07-09 18:41 被阅读0次

    什么是ScheduledThreadPoolExecutor?

    在给定的延迟之后运行任务或者是定期执行任务
    本文只简单描述一下怎么使用,不涉及原理和源码,可以简单了解后自己去撸源码。

    构造

    ScheduledThreadPoolExecutor(int corePoolSize)
    ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)
    ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)
    ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)
    

    ScheduledThreadPoolExecutor方法

    类型 方法 描述
    protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) 修修改或替换用于执行可运行的任务
    protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) 修改或替换用于执行可运行的任务
    void execute(Runnable command) 零延迟执行命令
    boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() 获取执行程序已关闭是否继续执行现有定期任务的策略
    boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() 获取执行程序已关闭是否执行现有延迟任务的策略
    BlockingQueue<Runnable> getQueue() 返回执行程序使用的任务队列
    boolean getRemoveOnCancelPolicy() 获取在取消时是否应立即从工作队列中删除已取消任务的策略
    ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) 创建并执行一次操作,该操作在给定延迟后启用
    ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 创建并执行一个周期性操作,该操作在给定的初始延迟后首先启用,然后在给定的时间后再次启用,即第一次是initialDelay后执行,第二次是initialDelay + period后执行,第三次是 initialDelay + period*2 后执行,依次类推
    ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在一次执行的终止后开始,delay后开始执行下一次
    void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) 设置执行程序关闭是否继续执行现有定期任务的策略
    void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) 设置关闭后执行程序是否也执行现有延迟任务的策略
    void setRemoveOnCancelPolicy(boolean value) 设置取消时任务时是否应立即从工作队列中删除已取消任务的策略
    void shutdown() 启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务
    List<Runnable> shutdownNow() 尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表
    <T> Future<T> submit(Callable<T> task) 提交有返回值的Callable任务
    Future<?> submit(Runnable task) 提交有返回值的Runnable任务
    <T> Future<T> submit(Runnable task, T result) 提交有返回值的Callable任务

    ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,所以也继承了ThreadPoolExecutor方法,ThreadPoolExecutor有哪些方法可以去Java API规范中去查看,也可以到java线程池 - ThreadPoolExecutor中查看。

    例子

    • schedule(Runnable command, long delay, TimeUnit unit)
      执行没有返回值的Runnable任务
    package com.sy.thread.example;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.concurrent.*;
    
    /**
     * Description: thread
     *
     * @author songyu
     */
    public class ScheduledThreadPoolExecutorTest {
        public static void main(String[] args) throws Exception {
            DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //创建线程池
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
                //根据需要重写方法
            };
            //没有返回值的任务
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    LocalDateTime now = LocalDateTime.now();
                    System.out.println(now.format(fmTime) + " Runnable开始执行");
                }
            });
            //schedule(Runnable command, long delay, TimeUnit unit)
            //延迟2秒执行,没有返回值
            LocalDateTime now1 = LocalDateTime.now();
            System.out.println(now1.format(fmTime) + " 将Runnable延迟任务加入线程池,一秒后开始执行");
            executor.schedule(thread,2, TimeUnit.SECONDS);
        }
    }
    

    执行结果

    2020-07-09 14:48:16 将Runnable延迟任务加入线程池,一秒后开始执行
    2020-07-09 14:48:18 Runnable开始执行
    
    • schedule(Callable<V> callable, long delay, TimeUnit unit)
      执行有返回值的Callable任务
    package com.sy.thread.example;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.concurrent.*;
    
    /**
     * Description: thread
     *
     * @author songyu
     */
    public class ScheduledThreadPoolExecutorTest2 {
        public static void main(String[] args) throws Exception {
            DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //创建线程池,、
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
                //根据需要重写方法
            };
    
            //有返回值的任务
            Callable callable = new Callable() {
                @Override
                public Object call() throws Exception {
                    LocalDateTime now = LocalDateTime.now();
                    System.out.println(now.format(fmTime) + " Callable开始执行");
                    return "hello world";
                }
            };
    
            //schedule(Callable<V> callable, long delay, TimeUnit unit)
            //延迟五秒执行 有返回值
            LocalDateTime now2 = LocalDateTime.now();
            System.out.println(now2.format(fmTime) + " 将Callable延迟任务加入线程池,一秒后开始执行");
            Future future = executor.schedule(callable,5, TimeUnit.SECONDS);
            System.out.println("Callable任务返回内容为:" + future.get());
        }
    }
    

    执行结果

    2020-07-09 14:54:49 将Callable延迟任务加入线程池,一秒后开始执行
    2020-07-09 14:54:54 Callable开始执行
    Callable任务返回内容为:hello world
    
    • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
      执行周期性定时任务
      command: 任务
      initialDelay:初次执行的延迟时间
      period: 执行周期时间
      第一次是initialDelay后执行,第二次是initialDelay + period后执行,第三次是 initialDelay + period * 2,以此类推
    package com.sy.thread.example;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Description: thread
     *
     * @author songyu
     */
    public class ScheduledThreadPoolExecutorTest3 {
        public static void main(String[] args) {
            DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //创建线程池
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
                //根据需要重写方法
            };
    
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    LocalDateTime now = LocalDateTime.now();
                    System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
                }
            });
            //scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
            //initialDelay 第一次延迟执行时间
            //period 周期时间
            //将任务提交到线程池,5秒后执行第一次任务,然后每隔10s执行一次
            LocalDateTime now = LocalDateTime.now();
            System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
            executor.scheduleAtFixedRate(thread,5,10, TimeUnit.SECONDS);
        }
    }
    

    执行结果

    2020-07-09 15:05:17 将Runnable周期任务加入线程池,一秒后开始执行
    2020-07-09 15:05:22 Runnabled周期任务开始执行
    2020-07-09 15:05:32 Runnabled周期任务开始执行
    2020-07-09 15:05:42 Runnabled周期任务开始执行
    2020-07-09 15:05:52 Runnabled周期任务开始执行
    2020-07-09 15:06:02 Runnabled周期任务开始执行
    2020-07-09 15:06:12 Runnabled周期任务开始执行
    2020-07-09 15:06:22 Runnabled周期任务开始执行
    2020-07-09 15:06:32 Runnabled周期任务开始执行
    ......
    
    • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
      执行周期性定时任务
      command: 任务
      initialDelay:初次执行的延迟时间
      period: 执行周期时间
      第一次是initialDelay后执行,第二次是在第一次任务执行完成后开始算,period后执行,第三次是在第二次任务执行完成后开始算,period后执行,以此类推
    package com.sy.thread.example;
    
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Random;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Description: thread
     *
     * @author songyu
     */
    public class ScheduledThreadPoolExecutorTest4 {
        public static void main(String[] args) {
            DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //创建线程池
            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
                //根据需要重写方法
            };
    
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        LocalDateTime now = LocalDateTime.now();
                        System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
                        Random random = new Random();
                        int randomNumber1 = random.nextInt(10) * 1000;
                        System.out.println("阻塞" + randomNumber1 + "毫秒");
                        Thread.sleep(randomNumber1);
                        LocalDateTime now2 = LocalDateTime.now();
                        System.out.println(now2.format(fmTime) + " Runnabled周期任务执行结束");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            //scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
            //initialDelay 第一次延迟执行时间
            //period 周期时间
            //将任务提交到线程池,5秒后执行第一次任务,第一次执行完成后,10秒后执行下一次,除了第一次执行,后续的执行都是从上一个任务完成后开始算,period时间后执行
            LocalDateTime now = LocalDateTime.now();
            System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
            executor.scheduleWithFixedDelay(thread,5,10, TimeUnit.SECONDS);
        }
    }
    

    执行结果

    2020-07-09 15:26:04 将Runnable周期任务加入线程池,一秒后开始执行
    2020-07-09 15:26:09 Runnabled周期任务开始执行
    阻塞8000毫秒
    2020-07-09 15:26:17 Runnabled周期任务执行结束
    2020-07-09 15:26:27 Runnabled周期任务开始执行
    阻塞3000毫秒
    2020-07-09 15:26:30 Runnabled周期任务执行结束
    2020-07-09 15:26:40 Runnabled周期任务开始执行
    阻塞8000毫秒
    2020-07-09 15:26:48 Runnabled周期任务执行结束
    2020-07-09 15:26:58 Runnabled周期任务开始执行
    阻塞9000毫秒
    2020-07-09 15:27:07 Runnabled周期任务执行结束
    2020-07-09 15:27:17 Runnabled周期任务开始执行
    阻塞1000毫秒
    2020-07-09 15:27:18 Runnabled周期任务执行结束
    2020-07-09 15:27:28 Runnabled周期任务开始执行
    ......
    

    ScheduledThreadPoolExecutor的execute()和submit()

    execute() > schedule(Runnable command, long delay, TimeUnit unit)
    submit() > schedule(Callable<V> callable, long delay, TimeUnit unit)

    public void execute(Runnable command) {
      schedule(command, 0, NANOSECONDS);
    }
    
    public Future<?> submit(Runnable task) {
      return schedule(task, 0, NANOSECONDS);
    }
    

    上面几个简单的例子把ScheduledThreadPoolExecutor几种任务执行的方式都简单的实现了一下,自己可以扩展一下,然后把剩余的方法和学习一下。

    相关文章

      网友评论

          本文标题:java线程池 - ScheduledThreadPoolExe

          本文链接:https://www.haomeiwen.com/subject/zlxhcktx.html