欢迎光临
一个有态度、有温度的分享型博客

Java中ScheduledThreadPoolExecutor实现定时周期性任务

在Java中我们如果要实现定时周期性的任务,ScheduledThreadPoolExecutor会是我们的首选,本文的工作就是了解此类的使用:

代码清单1:Task1

package xyz.rxblog;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.Callable;
public class Task1 implements Callable<String> {
    @Override
    public String call() throws Exception {
        String base = "2sdfasdf2e3reasdfasdf";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        int num = 0;
        for (int i = 0; i < 10; i++) {
            num = random.nextInt(base.length());
            sb.append(base.charAt(num));
        }
        System.out.println("Task running :" + new Date());
        return sb.toString();
    }
}

此类的作用是:生成10个字符字符串,使用Callable的目的是我们不在任务中直接输出结果,而主动获取任务的结果。

代码清单2:LongTask

package xyz.rxblog;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class LongTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("LongTask running: "+new Date());  
        TimeUnit.SECONDS.sleep(10);  
        return "success";  
    }
}

此类的作用是:让任务沉睡10s,然后返回一个“success”。

代码清单3:ScheduleThreadDemo

package xyz.rxblog;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ScheduleThreadDemo {
    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(
                2);
        ScheduledFuture future1 = executor.schedule(new Task1(), 5,
                TimeUnit.SECONDS);
        ScheduledFuture future2 = executor.schedule(new LongTask(), 3,
                TimeUnit.SECONDS);

        BlockingQueue<ScheduledFuture> blockingQueue = new ArrayBlockingQueue<ScheduledFuture>(
                2, true);
        // 想BlockingQueue中存放对象,如果可以容纳,返回true,否则抛出异常
        blockingQueue.add(future2);
        blockingQueue.add(future1);

        System.out.println(new Date());
        // 如果BlockingQueue不为空
        while (!blockingQueue.isEmpty()) {
            // 取走BlockingQueue中排在首位的对象,取不到返回null
            ScheduledFuture future = blockingQueue.poll();
            // 如果没有执行
            if (!future.isDone()) {
                // 将任务再次加入队列
                blockingQueue.add(future);
            } else {
                // 若果执行了,返回执行结果
                System.out.println(future.get());
            }
        }
        System.out.println(new Date());
        executor.shutdown();
    }
}

此类的作用是定时执行任务,我们定义了一个ScheduledThreadPoolExecutor,它的池长度为2,提交的任务中:第一个任务延迟5秒执行,第二个任务延迟3秒执行;然后我们定义了一个BlockingQueue,用它来存储ScheduleFuture,使用ScheduleFuture可以获得任务的执行结果,在一个while循环中,我们每次将一个ScheduledFuture从队列中弹出,验证它是否被执行,如果没有被执行则再次将它加入队列中,如果被执行了,这使用ScheduledFuture的get方法获取任务执行的结果。

看一下执行结果:

 Mon Nov 03 20:39:15 CST 2014
    LongTask running: Mon Nov 03 20:39:18 CST 2014
    Task running :Mon Nov 03 20:39:20 CST 2014
    dss2a2fffe
    success
    Mon Nov 03 20:39:28 CST 2014

从执行结果来看,长任务先执行,因为长任务延迟3s,然后是输出字符串任务,两个任务相差2s,任务从开始到结束时间差为13s,说明是多线程执行的。

参考文献:http://victorzhzh.iteye.com/blog/1011635;

Java中Timer和ThreadPoolExecutor学习比较系列文章:

  1. Java中Timer和ThreadPoolExecutor的区别和比较
  2. Java中使用Timer和TimerTask完成定时执行任务
  3. Java中ScheduledThreadPoolExecutor实现定时周期性任务
  4. 详细了解Java中定时器Timer的使用及缺陷分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址