• ScheduledExecutorService定时方法


    ScheduledExecutorService是java.util.concurrent并发包下的一个接口,表示调度服务~,它定义了以下几个方法:

    public ScheduledFuture<?> schedule(Runnable command,
    long delay, TimeUnit unit);

    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
    long delay, TimeUnit unit);

    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
    long initialDelay,
    long period,
    TimeUnit unit);

    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
    long initialDelay,
    long delay,
    TimeUnit unit); 
     

    前2个的任务是指定在延迟时间后执行一次任务,后2个方法则表示每间隔一段时间定时执行任务。

    ScheduledExecutorService的后两个方法比较容易搞混,下面就用小例子来搞清楚:

    public class DiffTest {

    private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) {
    final long executeTime = (long) (Math.random()*10);


    //scheduleAtFixedRate
    executor.scheduleAtFixedRate(new Runnable(){
    //模拟耗时任务,耗时是10s以内的任意数
    @Override
    public void run() {
    try {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    System.out.print(sdf.format(new Date()) + " 开始执行, ");
    Thread.sleep(3000);//3s
    System.out.println(sdf.format(new Date()) + "结束执行 ================");
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }, 0, 5, TimeUnit.SECONDS);//每隔5s


    }

    }
     当间隔时间(5s)大于任务的执行时间(3s),运行结果为:

    12:00:03 开始执行, 12:00:06结束执行 ================

    12:00:08 开始执行, 12:00:11结束执行 ================

    12:00:13 开始执行, 12:00:16结束执行 ================

    12:00:18 开始执行, 12:00:21结束执行 ================

    12:00:23 开始执行, 12:00:26结束执行 ================

    12:00:28 开始执行, 12:00:31结束执行 ================

    当间隔时间(5s)小于程序(7s)执行时间(将耗时改为7s, 每隔5s的设置就会失效)

    12:01:26 开始执行, 12:01:33结束执行 ================

    12:01:33 开始执行, 12:01:40结束执行 ================

    12:01:40 开始执行, 12:01:47结束执行 ================

    12:01:47 开始执行, 12:01:54结束执行 ================

    12:01:54 开始执行, 12:02:01结束执行 ================

    12:02:01 开始执行, 12:02:08结束执行 ================

    说明:scheduleAtFixedRate是以上一次任务的开始时间为间隔的,并且当任务执行时间大于设置的间隔时间时,真正间隔的时间由任务执行时间为准!

    再来测试下scheduleWithFixedDelay:

    executor.scheduleWithFixedDelay(new Runnable(){
    //模拟耗时任务,耗时是10s以内的任意数
    @Override
    public void run() {
    try {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    System.out.print(sdf.format(new Date()) + " 开始执行, ");
    Thread.sleep(3000);//3s
    System.out.println(sdf.format(new Date()) + "结束执行 ================");
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }, 0, 5, TimeUnit.SECONDS);//每隔5s
      当间隔时间(5s)大于任务的执行时间(3s),运行结果为:

    12:46:54 开始执行, 12:46:57结束执行 ================

    12:47:02 开始执行, 12:47:05结束执行 ================

    12:47:10 开始执行, 12:47:13结束执行 ================

    12:47:18 开始执行, 12:47:21结束执行 ================

    12:47:26 开始执行, 12:47:29结束执行 ================

    12:47:34 开始执行, 12:47:37结束执行 ================

    当间隔时间(5s)小于程序(7s)执行时间,此时运行结果为:

    12:48:12 开始执行, 12:48:19结束执行 ================

    12:48:24 开始执行, 12:48:31结束执行 ================

    12:48:36 开始执行, 12:48:43结束执行 ================

    12:48:48 开始执行, 12:48:55结束执行 ================

    12:49:00 开始执行, 12:49:07结束执行 ================

    12:49:12 开始执行, 12:49:19结束执行 ================

    说明:scheduleWithFixedDelay是以上一次任务的结束时间为间隔的!

    顺便说下,当定时调度遇到异常时,是否会影响下次任务的执行:

    public class DiffTest {

    private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    private static int a;

    private static int[] aa = {1,2,3};

    public static void main(String[] args) {

    //scheduleAtFixedRate
    executor.scheduleWithFixedDelay(new Runnable(){
    //模拟耗时任务,耗时是10s以内的任意数
    @Override
    public void run() {
    try {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    System.out.println(sdf.format(new Date()) + " 开始执行");
    System.out.println("执行结果:" + aa[a++]);
    System.out.println("==============");

    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    }, 0, 5, TimeUnit.SECONDS);//每隔5s
    }
    }
     运行之,结果为:

    19:13:07 开始执行

    执行结果:1

    ==============

    19:13:12 开始执行

    执行结果:2

    ==============

    19:13:17 开始执行

    执行结果:3

    ==============

    19:13:22 开始执行

    java.lang.ArrayIndexOutOfBoundsException: 3

    at com.nineclient.echat.plugin.DiffTest$1.run(DiffTest.java:28)

    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)

    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)

    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)

    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)

    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

    at java.lang.Thread.run(Thread.java:722)

    19:13:27 开始执行

    java.lang.ArrayIndexOutOfBoundsException: 4

    at com.nineclient.echat.plugin.DiffTest$1.run(DiffTest.java:28)

    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)

    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)

    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)

    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)

    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

    at java.lang.Thread.run(Thread.java:722)

    这说明,虽然执行到第4次时发生了异常,但并不影响下一次的执行。但如果你没有异常捕获机制,则会影响,比如改成:

    executor.scheduleWithFixedDelay(new Runnable(){
    //模拟耗时任务,耗时是10s以内的任意数
    @Override
    public void run() {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    System.out.println(sdf.format(new Date()) + " 开始执行");
    System.out.println("执行结果:" + aa[a++]);
    System.out.println("==============");
    }

    }, 0, 5, TimeUnit.SECONDS);//每隔5s
     运行结果为:

    19:14:39 开始执行

    执行结果:1

    ==============

    19:14:44 开始执行

    执行结果:2

    ==============

    19:14:49 开始执行

    执行结果:3

    ==============

    19:14:54 开始执行

    之后就不再运行了。。所以务必在被调度的任务上加上异常捕获!
    ————————————————
    原文链接:https://blog.csdn.net/qq_18875541/article/details/69393631

  • 相关阅读:
    个人觉得在前台比较通用的校验的提示方法
    平时面试总结
    sturts2批量导入excel中的信息入库大致代码
    在B/S系统中得到spring的ApplicationContext对象的一点小技巧
    Oracle同义词创建及其作用
    Oracle中创建dblink的方法
    真实项目中struts2 导出excel文件
    十二款jQuery插件(编辑器,图片,验证等)
    华丽到暴表的网站 cnn ecosphere
    Mysql 临时表
  • 原文地址:https://www.cnblogs.com/gaoruideboke/p/14489642.html
Copyright © 2020-2023  润新知