Java定时任务-ScheduledExecutorService

1.ScheduledExecutorService的接口介绍


package java.util.concurrent;

public interface ScheduledExecutorService extends ExecutorService {
    
    

   //单次执行,在指定延时delay后运行command任务
    public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);

   //单次执行,在指定延时delay后运行callable任务
    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);

}

(1)ScheduledExecutorService接口中包含四个方法进行任务的定时调度,解释分别如上。
(2)对于 固定延时 的任务时在任务执行后开始计算的,第一次任务是在initialDelay后,第二次任务是在第一次任务执行完以后,再加上delay。

2.ScheduledExecutorService的实现类:ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor的定义

//继承线程池、实现ScheduledExecutorService接口
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService

ScheduledThreadPoolExecutor 的构造方法:跟线程的构造差不多,不多做介绍

public ScheduledThreadPoolExecutor(int corePoolSize);

public ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory);

public ScheduledThreadPoolExecutor(int corePoolSize,RejectedExecutionHandler handler);

public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) ;

说明:并发包下的:Executors类也提供了创建ScheduledExecutorService的方法,但是阿里巴巴的开发规范中不建议这么用,还是显示的创建线程池会比较好

java.util.concurrent.Executors#newSingleThreadScheduledExecutor();
java.util.concurrent.Executors#newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);

java.util.concurrent.Executors#newScheduledThreadPool(int);
java.util.concurrent.Executors#newScheduledThreadPool(int, java.util.concurrent.ThreadFactory);

3.ScheduledExecutorService定时调度的一些实例分析

任务一:

 /**
     * 任务一:
     */
    public class Task1 implements Runnable{
    
    
        @Override
        public void run() {
    
    
            String threadName = Thread.currentThread().getName();
            System.out.println("[当前线程是:"+threadName+",执行定时任务1:"+System.currentTimeMillis()+"]");
        }
    }

任务二:

/**
     * 任务2:
     */
    public class Task2 implements Runnable{
    
    
        @Override
        public void run() {
    
    
            String threadName = Thread.currentThread().getName();
            System.out.println("[当前线程是:"+threadName+",执行定时任务1:"+System.currentTimeMillis()+"]");
            try {
    
    
                Thread.sleep(10000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }

测试场景一:

Task1 task1=new Task1();
Task2 task2=new Task2();

ScheduledExecutorService service=new ScheduledThreadPoolExecutor(10);

//重复执行,启动延迟一秒执行,每隔一秒反复执行任务一
service.scheduleAtFixedRate(task1,1,1, TimeUnit.SECONDS);
//启动后,延迟两秒在执行任务二,但是任务一并没有堵塞
service.schedule(task2,2,TimeUnit.SECONDS);

现象
(1)任务一:重复执行,启动延迟一秒执行,每隔一秒反复执行。
(2)任务二:启动延迟两秒后执行,同时任务内线程堵塞10秒中。
(3)任务一的执行并不会被任务二的中的Thread.sleep(10000)给堵塞,因为ScheduledExecutorService的任务调度执行是多线程的。
在这里插入图片描述

测试场景二:
咱们修改一下任务二:在任务二中抛出 异常
任务一还是跟上面一样

public class Task2 implements Runnable {
    
    

    @Override
    public void run() {
    
    
        String threadName = Thread.currentThread().getName();
        System.out.println("[当前线程是:"+threadName+",执行定时任务2:"+System.currentTimeMillis()+"]");
        throw new RuntimeException("我们尝试在 任务二 中抛出一个异常");
    }
}

测试代码:任务一和任务二都是反复执行的任务类型

  Task1 task1=new Task1();
  Task2 task2=new Task2();

  ScheduledExecutorService service=new ScheduledThreadPoolExecutor(10);

  service.scheduleAtFixedRate(task1,1,1, TimeUnit.SECONDS);
  
  service.scheduleAtFixedRate(task2,3,1, TimeUnit.SECONDS);

现象:
在这里插入图片描述
(1)任务二抛出了异常,任务二将不再执行(停止),但是异常并不会在调用方抛出,所以需要在任务二的run方法中处理异常。
(2)任务一并不受影响。

4.总结(主要是与Timer的不同)

(1)ScheduledExecutorService 使用的是线程池实现,可以有多个线程执行任务。
(2)它在任务执行后再设置下次执行的时间,对于固定延时的任务更为合理。
(3)一个定时任务的异常并不会影响其他定时任务的执行,但是当一个定时任务发生异常的时候,哪怕是重复执行的任务都不会再被调度。

猜你喜欢

转载自blog.csdn.net/weixin_43911286/article/details/113278312