Timer与ScheduledThreadPoolExecutor的比较

推荐还是用第二种方法,即用ScheduledThreadPoolExecutor,因为它不需要像timer那样需要在里面再用一个线程池来保证计时的准确。(前提是线程池必须要大于1个线程)

1.timer中用线程池来执行任务,可以保证开始执行时间的准确,具体结束时间要以任务需要执行时间为准。如果未使用线程池,执行时间将被任务执行时间所影响。

package timer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.core.joran.action.NewRuleAction;

public class test {
    private static final Logger log = LoggerFactory.getLogger(test.class);

    SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) throws InterruptedException {
        log.info("main start");
        Timer timer = new Timer();
        MyTask myTask = new MyTask("ONE");
        MyTask myTask2 = new MyTask("TWO");
        // 多长时间(毫秒)后执行任务
        // timer.schedule(new MyTask(), 1000);
        // 设定某个时间执行任务
        // timer.schedule(new MyTask(), new Date(System.currentTimeMillis() +
        // 1000 * 2));
        // 第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。
        // timer.schedule(new MyTask(), new Date(System.currentTimeMillis() +
        // 1000 * 60*3),1000);
        // delay时间后开始执行任务,并每隔period时间调用任务一次。
        timer.scheduleAtFixedRate(myTask, 1000 * 3, 3000);
//        timer.scheduleAtFixedRate(myTask2, 1000 * 3, 3000);
        // 第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。
        // timer.scheduleAtFixedRate(myTask, new Date(System.currentTimeMillis()
        // + 1000 * 1), 2000);

        TimeUnit.SECONDS.sleep(10);
        // timer.cancel();
//        myTask.cancel();
//        myTask2.cancel();
        log.info("timer cancel");
    }
}

class MyTask extends TimerTask {
    ExecutorService mExecutorService= Executors.newFixedThreadPool(3);
    private static final Logger log = LoggerFactory.getLogger(test.class);
    SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private String s;

    public MyTask(String s) {
        this.s = s;
    }

    @Override
    public void run() {
        
        mExecutorService.execute(new Runnable() {
            public void run() {
                log.info(s + " 1 " + sdformat.format(new Date(System.currentTimeMillis())));
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info(s + " 2 " + sdformat.format(new Date(System.currentTimeMillis())));
            }
        });
        
        
    }
}

2.ScheduledThreadPoolExecutor类分scheduleWithFixedDelay和scheduleAtFixedRate方法,前者不包含执行时间,后者包含执行时间。

两种方法中如果都不再使用线程池,执行的开始时间也都会受执行时间影响。

package timer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ScheduledThreadPoolExecutorTest {
    private static final Logger log = LoggerFactory.getLogger(test.class);
    SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) throws InterruptedException {
        MyTask2 task = new MyTask2("ONE");
        MyTask2 task2 = new MyTask2("TWO");
        ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(5);
//        stpe.scheduleWithFixedDelay(task, -2, 3, TimeUnit.SECONDS);
//        stpe.scheduleWithFixedDelay(task2, -2, 3, TimeUnit.SECONDS);
        ScheduledFuture<?> sf=stpe.scheduleAtFixedRate(task, -2, 3, TimeUnit.SECONDS);
        TimeUnit.SECONDS.sleep(3);
//        sf.cancel(false);
//        stpe.shutdown();
    }
}

class MyTask2 extends TimerTask {
    private static final Logger log = LoggerFactory.getLogger(test.class);
    SimpleDateFormat sdformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    private String s;

    public MyTask2(String s) {
        this.s = s;
    }
    
    @Override
    public void run() {
        log.info(s + " 1 " + sdformat.format(new Date(System.currentTimeMillis())));
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(s + " 2 " + sdformat.format(new Date(System.currentTimeMillis())));
    }
}
原文地址:https://www.cnblogs.com/zhuawang/p/4557572.html