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

所谓定时任务有两个核心要素:
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)

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值