将如下代码保存到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/