zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    DEDECMS里面DEDE函数解析
    dede数据库类使用方法 $dsql
    DEDE数据库语句 DEDESQL命令批量替换 SQL执行语句
    织梦DedeCms网站更换域名后文章图片路径批量修改
    DSP using MATLAB 示例 Example3.12
    DSP using MATLAB 示例 Example3.11
    DSP using MATLAB 示例 Example3.10
    DSP using MATLAB 示例Example3.9
    DSP using MATLAB 示例Example3.8
    DSP using MATLAB 示例Example3.7
  • 原文地址:https://www.cnblogs.com/gaoruideboke/p/14489642.html
Copyright © 2011-2022 走看看