全面解析schedule、scheduleAtFixedRate和scheduleWithFixedDelay

通过java在做定时任务的时候最好使用scheduleThreadPoolExecutor的方式,因为这样可以保证里面始终以后线程是活的。scheduleThreadPoolExecutor有三种任务

执行的方式:

scheduleAtFixedRate(commod,initialDelay,period,unit)

initialDelay是说系统启动后,需要等待多久才开始执行。

period为固定周期时间,按照一定频率来重复执行任务。

如果period设置的是3秒,系统执行要5秒;那么等上一次任务执行完就立即执行,也就是任务与任务之间的差异是5s;

如果period设置的是3s,系统执行要2s;那么需要等到3S后再次执行下一次任务。

public static void main(String[] args) {
        ScheduledExecutorService respScheduler = new ScheduledThreadPoolExecutor(2);
        System.out.println("task begin:"+System.currentTimeMillis()/1000);
        respScheduler.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);//2000
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"--task run:"+System.currentTimeMillis()/1000);
            }
        },2,3, TimeUnit.SECONDS);}
当任务执行耗时为5s时:

task begin:1497945641
pool-1-thread-1--task run:1497945648
pool-1-thread-1--task run:1497945653
pool-1-thread-1--task run:1497945658

pool-1-thread-2--task run:1497945663
当任务执行耗时为2s时

task begin:1497945571
pool-1-thread-1--task run:1497945575
pool-1-thread-1--task run:1497945578

pool-1-thread-1--task run:1497945581

scheduleWithFixedDelay(commod,initialDelay,delay,unit)

initialDelay是说系统启动后,需要等待多久才开始执行。

period为固定周期时间,按照一定频率来重复执行任务。

这个方式必须等待上一个任务结束才开始计时period。

如果设置的period为3s;任务执行耗时为5S那么下次任务执行时间为第8S。

public static void main(String[] args) {
        ScheduledExecutorService respScheduler = new ScheduledThreadPoolExecutor(2);
        System.out.println("task begin:"+System.currentTimeMillis()/1000);
        respScheduler.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"--task run:"+System.currentTimeMillis()/1000);
            }
        },2,3, TimeUnit.SECONDS);
}}
task begin:1497945822
pool-1-thread-1--task run:1497945829
pool-1-thread-1--task run:1497945837
pool-1-thread-1--task run:1497945845
pool-1-thread-1--task run:1497945853
pool-1-thread-1--task run:1497945861
间隔8S

schedule(commod,initialDelay,unit))比较简单,系统开始initialDelay后开始执行commod任务,执行完完事。

public static void main(String[] args) {
            ScheduledExecutorService respScheduler = new ScheduledThreadPoolExecutor(2);
            System.out.println("task begin:"+System.currentTimeMillis()/1000);
            respScheduler.schedule(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"--task run:"+System.currentTimeMillis()/1000);
                }
            },2,TimeUnit.SECONDS);
    }}
task begin:1497946055
pool-1-thread-1--task run:1497946062


如果把上面的任务方式写在一起就和线程池有关系了

public static void main(String[] args) {
        ScheduledExecutorService respScheduler = new ScheduledThreadPoolExecutor(2);
        System.out.println("task begin:"+System.currentTimeMillis()/1000);
        respScheduler.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"--task1 run:"+System.currentTimeMillis()/1000);
            }
        },2,3, TimeUnit.SECONDS);
        System.out.println("main Thread gogogo");
        respScheduler.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"--task2 run:"+System.currentTimeMillis()/1000);
            }
        },2,3, TimeUnit.SECONDS);
        System.out.println("main Thread gogogo222");
        respScheduler.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"--task3 run:"+System.currentTimeMillis()/1000);
            }
        },2,TimeUnit.SECONDS);
}}

task begin:1497946437
main Thread gogogo
main Thread gogogo222
pool-1-thread-2--task1 run:1497946444
pool-1-thread-1--task2 run:1497946444 //线程池两个线程,所以同时执行
pool-1-thread-2--task3 run:1497946449//需要等待其中一个任务执行完,用空的线程才执行task3

pool-1-thread-1--task1 run:1497946449
pool-1-thread-2--task2 run:1497946454//距离上一个task2并不是8s而是10s 是因为没有空余的线程,所以需要多等待一会。
pool-1-thread-1--task1 run:1497946454
pool-1-thread-1--task1 run:1497946459

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值