Java多线程/并发03、实现定时任务的3种方法

来源:互联网 发布:淘宝卖家不开发票 编辑:程序博客网 时间:2024/06/13 05:47

所谓定时任务有两个核心要素:
1、任务开始时间:可以指定任务在将来某个时间点运行,或者指定任务从现在开始延迟一个时间段运行
2、任务执行周期:可以指定该任务每间隔多久执行一次

Java实现定时任务有三种方法:

一、利用Thread及Sleep实现,通过while循环让其不停运行

public class TimerTaskDemo {    public static void main(String[] args) {        Runnable runable=new Runnable() {            @Override            public void run() {                System.out.println("子线程执行任务,当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));            }        };        try {            System.out.println("主线程启动子线程时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));            scheduleThread(5L,3,runable);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    /***     *      * @param duration 指定什么时间后运行 单位:秒     * @param timeInterval 每次运行间隔时间 单位:秒     * @param runnable 待运行的Runable对象     * @throws InterruptedException     */    static void scheduleThread(Long duration,Integer timeInterval,Runnable runnable) throws InterruptedException{        /*阻塞等待*/        TimeUnit.SECONDS.sleep(duration);        //Thread.sleep(duration*1000);        final Runnable interiorRun=runnable;        final Integer interiorTimeInterval=timeInterval;        /*运行*/        new Thread(new Runnable() {            @Override            public void run() {                while(true){                    /*执行方法*/                    interiorRun.run();                    try {                        /*任务执行间隔*/                        TimeUnit.SECONDS.sleep(interiorTimeInterval);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }}

二、利用Timer和TimerTask

先说下两者关联和区别:
1、Timer是调度者,可以安排任务执行计划,包括:任务时间、执行频率,也可停止任务。
2、TimerTask是任务。Timer类可以调度TimerTask任务,TimerTask则通过在run()方法里实现具体任务。TimerTask也可停止自身任务。
3、一个Timer可以调度多个TimerTask。
4、Timer是单线程的:Timer构造函数调用时会创建了一个新线程,所有TimerTask都是依靠这个新的线程执行。默认线程名:Timer-0

模拟一个进度条:

public class TimerTaskDemo {    public static void main(String[] args) {        Timer timer = new Timer();           MyTimerTask mytask=new MyTimerTask();            timer.schedule(mytask, 0, 300);         try {            TimeUnit.SECONDS.sleep(10);            /*10秒后停止任务*/            mytask.cancel();//停止运行指定的TimerTask            //timer.cancel();//停止运行timer上所有TimerTask            System.out.print("100%");        } catch (InterruptedException e) {            e.printStackTrace();        }    }    static class MyTimerTask extends java.util.TimerTask {        public void run() {            System.out.print(">");        }    }}

三、ScheduledExecutorService

Java SE 5后在JUC中提供了一个工具类:ScheduledExecutorService,这是最理想的定时任务实现方式。
相比于上两种方法,它有以下好处:
1、相比于Timer的单线程,它是通过线程池的方式来执行任务的。
2、可以很灵活的去设定第一次执行任务delay时间。
3、方法中提供TimeUnit,可设定时间单位。

public class TimerTaskDemo {    public static void main(String[] args) {        ScheduledExecutorService ses=Executors.newScheduledThreadPool(2);        ses.scheduleAtFixedRate(new MyTimerTask(), 2, 1, TimeUnit.SECONDS);        ses.scheduleAtFixedRate(new MyTimerTask(), 1, 1, TimeUnit.SECONDS);        try {            TimeUnit.SECONDS.sleep(10);            /*10秒后停止任务*/            ses.shutdown();//停止运行线程池上的所有runable。            System.out.print("--运行10秒停止--");        } catch (InterruptedException e) {            e.printStackTrace();        }    }    /*TimerTask实现Runable接口*/    static class MyTimerTask extends java.util.TimerTask {        public void run() {            System.out.println(Thread.currentThread().getName()+":"+ Calendar.getInstance().get(Calendar.SECOND));        }    }}

输出结果,可以看到开启了两个线程运行任务。(pool-1-thread-1及pool-1-thread-2)

0 0
原创粉丝点击