java实现定时任务的三种方式

所谓定时任务有两个核心要素: 
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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

二、利用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(">");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

三、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));
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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

转自 https://blog.csdn.net/soonfly/article/details/70917204

猜你喜欢

转载自blog.csdn.net/zhufengyan521521/article/details/80015237