初识 ScheduledThreadPoolExecutor

将如下代码保存到Wzf.java文件,使用javac编译,使用java运行即可。

Wzf.java

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import java.util.Date;
import java.text.SimpleDateFormat;

public class Wzf {
    private ScheduledExecutorService mGeneratorExecutor;
    private ScheduledFuture<?> mDataItemGeneratorFuture;

    public static void main(String[] args) {
       Wzf wzf = new Wzf();
       wzf.init();
       wzf.start();
    }

    public void init() {
        log("init", "init begin");
        mGeneratorExecutor = new ScheduledThreadPoolExecutor(1);
        log("init", "init end");
    }

    public void start() {
        log("start", "start begin");
        mDataItemGeneratorFuture = mGeneratorExecutor.scheduleWithFixedDelay(//scheduleAtFixedRate
                new DataItemGenerator(), 1, 5, TimeUnit.SECONDS);
        log("start", "start end");
    }

    public void stop() {
        log("stop", "stop begin");
        mDataItemGeneratorFuture.cancel(true /* mayInterruptIfRunning */);
        log("stop", "stop end");
    }

    private class DataItemGenerator implements Runnable {
        @Override
        public void run() {
            log("run", "run.......111");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
            }
            log("run", "run.......222");
        }
    }

    private void log(String tag, String msg) {
        long tId = Thread.currentThread().getId();
        String tName = Thread.currentThread().getName();
        
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss..SSS");
        String timeStr = df.format(new Date());
        System.out.println(timeStr + "    " + tName + "[" + tId + "]  " + tag + " : " + msg);
    }
}

运行log如下

2016-02-20 15:39:31..867    main[1]  init : init begin
2016-02-20 15:39:31..869    main[1]  init : init end
2016-02-20 15:39:31..870    main[1]  start : start begin
2016-02-20 15:39:31..871    main[1]  start : start end
2016-02-20 15:39:32..883    pool-1-thread-1[8]  run : run.......111
2016-02-20 15:39:35..892    pool-1-thread-1[8]  run : run.......222
2016-02-20 15:39:40..906    pool-1-thread-1[8]  run : run.......111
2016-02-20 15:39:43..916    pool-1-thread-1[8]  run : run.......222
2016-02-20 15:39:48..922    pool-1-thread-1[8]  run : run.......111
2016-02-20 15:39:51..933    pool-1-thread-1[8]  run : run.......222
2016-02-20 15:39:56..938    pool-1-thread-1[8]  run : run.......111
从log看,执行start之后,循环在其他线程中处理某项事务,第一次延迟1s执行,其余都是延迟5s执行。两个时间间隔是用参数设置的。


scheduleWithFixedDelay与scheduleAtFixedRate的区别:

前者是固定的时间间隔,即前一个事务处理完之后,间隔5s,再执行下一个事务处理。

后者是固定的频率,即两次事务开始处理的时间间隔是5s。如果事务处理比较耗时,超过了间隔时间,则会在前一个事务处理完后,马上开始执行下一个事务处理。


Timer与ScheduledThreadPoolExecutor的区别:
Timer对调度的支持是基于绝对时间的,因此任务对系统时间的改变是敏感的;而ScheduledThreadPoolExecutor支持相对时间。
Timer使用单线程方式来执行所有的TimerTask,如果某个TimerTask很耗时则会影响到其他TimerTask的执行;
而ScheduledThreadPoolExecutor则可以构造一个固定大小的线程池来执行任务。
Timer 不会捕获由TimerTask抛出的未检查异常,故当有异常抛出时,Timer会终止,导致未执行完的TimerTask不再执行,新的 TimerTask也不能被调度;
ScheduledThreadPoolExecutor对这个问题进行了妥善的处理,不会影响其他任务的执行。


获取系统当前时间,并格式化,显示毫秒:

import java.util.Date;
import java.text.SimpleDateFormat;

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss..SSS");
String timeStr = df.format(new Date());

参考:

http://hubingforever.blog.163.com/blog/static/17104057920109643632988/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章