zoukankan      html  css  js  c++  java
  • Java ScheduledThreadPoolExecutor延迟或周期性执行任务

    Java提供的Time类可以周期性地或者延期执行任务,但是有时我们需要并行执行同样的任务,这个时候如果创建多个Time对象会给系统带来负担,解决办法是将定时任务放到线程池中执行。

    Java的ScheduledThreadPoolExecutor类实现了ScheduledExecutorService接口中定义的以不同方法执行任务的方法。

    之前,我写过一篇关于Java ThreadPoolExecutor的文章中使用了Executors创建线程池。Executors类也提供了工厂方法创建ScheduledThreadPoolExecutor,并且可以设置线程池中的线程。

    假设有下面简单的Runnable类

    WorkerThread.java:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    package com.journaldev.threads;
     
    import java.util.Date;
     
    public class WorkerThread implements Runnable{
     
    private String command;
     
        public WorkerThread(String s){
            this.command=s;
        }
     
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" Start. Time = "+new Date());
            processCommand();
            System.out.println(Thread.currentThread().getName()+" End. Time = "+new Date());
        }
     
        private void processCommand() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
     
        @Override
        public String toString(){
            return this.command;
        }
    }

    下面的例子中worker线程将被延期10s执行上面的Rnnable类大约花费5s执行任务

    ScheduledThreadPool.java:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package com.journaldev.threads;
     
    import java.util.Date;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
     
    public class ScheduledThreadPool {
     
        public static void main(String[] args) throws InterruptedException {
            ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
     
            //schedule to run after sometime
            System.out.println("Current Time = "+new Date());
            for(int i=0; i<3; i++){
                Thread.sleep(1000);
                WorkerThread worker = new WorkerThread("do heavy processing");
                scheduledThreadPool.schedule(worker, 10, TimeUnit.SECONDS);
            }
     
            //add some delay to let some threads spawn by scheduler
            Thread.sleep(30000);
     
            scheduledThreadPool.shutdown();
            while(!scheduledThreadPool.isTerminated()){
                //wait for all tasks to finish
            }
            System.out.println("Finished all threads");
        }
     
    }

    运行上面的程序,可以得到下面的输出,由此可以确认任务在10s后才执行。

    1
    2
    3
    4
    5
    6
    7
    8
    Current Time = Tue Oct 29 15:10:03 IST 2013
    pool-1-thread-1 Start. Time = Tue Oct 29 15:10:14 IST 2013
    pool-1-thread-2 Start. Time = Tue Oct 29 15:10:15 IST 2013
    pool-1-thread-3 Start. Time = Tue Oct 29 15:10:16 IST 2013
    pool-1-thread-1 End. Time = Tue Oct 29 15:10:19 IST 2013
    pool-1-thread-2 End. Time = Tue Oct 29 15:10:20 IST 2013
    pool-1-thread-3 End. Time = Tue Oct 29 15:10:21 IST 2013
    Finished all threads

    注意到所有的schedule方法都返回了ScheduledFuture实例,可以用于获取线程状态信息和延迟时间。ScheduledFuture接口继承Future接口,更多信息见Java Callable Future Example.

    在ScheduledExecutorService中至少有2个方法可用于周期性执行任务。

    scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)

    我们可以使用该方法延迟执行任务,设置任务的执行周期。时间周期从线程池中首先开始执行的线程算起,所以假设period为1s,线程执行了5s,那么下一个线程在第一个线程运行完后会很快被执行。

    比如下面的代码

    1
    2
    3
    4
    5
    6
    for (int i = 0; i < 3; i++) {
        Thread.sleep(1000);
        WorkerThread worker = new WorkerThread("do heavy processing");
        // schedule task to execute at fixed rate
        scheduledThreadPool.scheduleAtFixedRate(worker, 0, 10,
                TimeUnit.SECONDS);
    输出
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Current Time = Tue Oct 29 16:10:00 IST 2013
    pool-1-thread-1 Start. Time = Tue Oct 29 16:10:01 IST 2013
    pool-1-thread-2 Start. Time = Tue Oct 29 16:10:02 IST 2013
    pool-1-thread-3 Start. Time = Tue Oct 29 16:10:03 IST 2013
    pool-1-thread-1 End. Time = Tue Oct 29 16:10:06 IST 2013
    pool-1-thread-2 End. Time = Tue Oct 29 16:10:07 IST 2013
    pool-1-thread-3 End. Time = Tue Oct 29 16:10:08 IST 2013
    pool-1-thread-1 Start. Time = Tue Oct 29 16:10:11 IST 2013
    pool-1-thread-4 Start. Time = Tue Oct 29 16:10:12 IST 2013
    scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit)
    该方法可被用于延迟周期性执行任务,delaytime是线程停止执行到下一次开始执行之间的延迟时间,假设有下面的代码
    1
    2
    3
    4
    5
    6
    for (int i = 0; i < 3; i++) {
        Thread.sleep(1000);
        WorkerThread worker = new WorkerThread("do heavy processing");
        scheduledThreadPool.scheduleWithFixedDelay(worker, 0, 1,
                TimeUnit.SECONDS);
    }
    输出结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Current Time = Tue Oct 29 16:14:13 IST 2013
    pool-1-thread-1 Start. Time = Tue Oct 29 16:14:14 IST 2013
    pool-1-thread-2 Start. Time = Tue Oct 29 16:14:15 IST 2013
    pool-1-thread-3 Start. Time = Tue Oct 29 16:14:16 IST 2013
    pool-1-thread-1 End. Time = Tue Oct 29 16:14:19 IST 2013
    pool-1-thread-2 End. Time = Tue Oct 29 16:14:20 IST 2013
    pool-1-thread-1 Start. Time = Tue Oct 29 16:14:20 IST 2013
    pool-1-thread-3 End. Time = Tue Oct 29 16:14:21 IST 2013
    pool-1-thread-4 Start. Time = Tue Oct 29 16:14:21 IST 2013
  • 相关阅读:
    ASE19团队项目 beta阶段 model组 scrum report list
    ASE19团队项目 beta阶段 model组 scrum7 记录
    ASE19团队项目 beta阶段 model组 scrum6 记录
    ASE19团队项目 beta阶段 model组 scrum5 记录
    ASE19团队项目 beta阶段 model组 scrum4 记录
    ASE19团队项目 beta阶段 model组 scrum3 记录
    ASE19团队项目 beta阶段 model组 scrum2 记录
    ASE19团队项目 beta阶段 model组 scrum1 记录
    【ASE模型组】Hint::neural 模型与case study
    【ASE高级软件工程】第二次结对作业
  • 原文地址:https://www.cnblogs.com/kuyuyingzi/p/4266338.html
Copyright © 2011-2022 走看看