Java - ScheduledExecutorService接口介绍(1)(可实现Timer定时器)

1. ScheduledExecutorService接口

1.1 Java官文API文档关于ScheduledExecutorService的介绍

  1. ScheduledExecutorService (Java SE 11 & JDK 11 ) (oracle.com)

  2. ExecutorService 接口介绍

1.2 ScheduledExecutorService 接口中的常用方法

Modifier and TypeMethodDescription
ScheduledFuture<?>schedule(Runnable command, long delay, TimeUnit unit)Submits a one-shot task that becomes enabled after the given delay.
<V> ScheduledFuture<V>schedule(Callable<V> callable, long delay, TimeUnit unit)Submits a value-returning one-shot task that becomes enabled after the given delay.
ScheduledFuture<?>scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)Submits a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is, executions will commence after initialDelay, then initialDelay + period, then initialDelay + 2 * period, and so on.
ScheduledFuture<?>scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)Submits a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.

在ExecutorService的基础上,ScheduledExecutorService提供了按时间安排执行任务的功能,它提供的方法主要有:

  • schedule(task,initDelay):安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。
  • scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行
  • scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。

note: 其中需要注意的是上述四个方法中,只有当delay时间之后才会将该task submit到线程池中,因此在submit之前该线程池中没有task任务,所以一定不要直接调用shutdown()方法,否则会立即将 ScheduledExecutorService 取消。

1.3 代码:ScheduleExecutorService的例子

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ScheduledExecutorServiceTest {
    public static void main(String[] args) {
        test01();
        System.out.println("----------------------------");
        test02();
    }

    private static void test01() {
        // 1 创建 ScheduledExecutorService 
        ScheduledExecutorService service=Executors.newScheduledThreadPool(2);
        // 2 创建task1
        Runnable task1=new Runnable() {
            public void run()
            {
                System.out.println("Taskrepeating1.");
            }
        };
        // 3 使用scheduleAtFixedRate()方法,将在0秒之后将该task提交到service线程池中
        final ScheduledFuture future1=service.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);

        // note: 下面的函数只有在delay 5s后才会将该task1提交到service中,又因为future2中的delay为10s,因此当执行shutdown方法后,会立即调用shutdownNow()而不会被阻塞。
        // final ScheduledFuture future3=service.scheduleAtFixedRate(task1,5,1,TimeUnit.SECONDS);

        // 4 创建future2,当delay 10s后会取消task1中的任务
        ScheduledFuture future2=service.schedule(new Callable() {
            public String call() {
                future1.cancel(true);
                return "taskcancelled!";
            }
        }, 10, TimeUnit.SECONDS);
        try {
            System.out.println(future2.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 5 调用shutdown()方法,该方法是阻塞的,只有当service的线程池中没有task时才会被执行。
        service.shutdown();
    }

    private static void test02() {
        // 1 创建 ScheduledExecutorService 
        ScheduledExecutorService service=Executors.newScheduledThreadPool(2);
        // 2 创建task1
        Runnable task1=new Runnable() {
            public void run()
            {
                System.out.println("Taskrepeating2.");
            }
        };

        // 3 下面的函数只有在delay 5s后才会将该task1提交到service中,又因为future2中的delay为10s,因此当执行shutdown方法之前没有调用future2.get(),会立即调用shutdownNow()而不会被阻塞。
        final ScheduledFuture future1=service.scheduleAtFixedRate(task1,5,1,TimeUnit.SECONDS);

        // 4 创建future2,当delay 10s后会取消task1中的任务
        ScheduledFuture future2=service.schedule(new Callable() {
            public String call() {
                future1.cancel(true);
                return "taskcancelled!";
            }
        }, 10, TimeUnit.SECONDS);
        try {
        	// note: 调用get()方法之后,只能通过cancel和Thread判断来取消get,
        	// 否则会一直执行到结束,具体介绍如 https://segmentfault.com/a/1190000007961347所示。
            System.out.println(future2.get()); // 调用get()方法,令其立即执行。
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 5 调用shutdown()方法,该方法是阻塞的,只有当service的线程池中没有task时才会被执行。
        service.shutdown();
    }
}

----执行结果:
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
Taskrepeating1.
taskcancelled!
----------------------------
Taskrepeating2.
Taskrepeating2.
Taskrepeating2.
Taskrepeating2.
Taskrepeating2.
Taskrepeating2.
taskcancelled!

这个例子有两个任务,第一个任务每隔一秒打印一句“Taskrepeating”,第二个任务在10秒钟后取消第一个任务。

  1. 初始化一个ScheduledExecutorService对象,这个对象的线程池大小为2。
  2. 用内函数的方式定义了一个Runnable任务。
  3. 调用所定义的ScheduledExecutorService对象来执行任务,任务每秒执行一次。能重复执行的任务一定是 Runnable类型。注意我们可以用TimeUnit来制定时间单位,这也是Java5.0里新的特征,5.0以前的记时单位是微秒,现在可精确到奈秒。
  4. 调用ScheduledExecutorService对象来执行第二个任务,第二个任务所作的就是在5秒钟后取消第一个任务。
  5. 关闭服务。

1.4 补充:ExecutorService 接口中的常用方法

Modifier and TypeMethodDescription
booleanawaitTermination(long timeout, TimeUnit unit)Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
<T> List<Future<T>>invokeAll(Collection<? extends Callable<T>> tasks)Executes the given tasks, returning a list of Futures holding their status and results when all complete.
<T> List<Future<T>>invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)Executes the given tasks, returning a list of Futures holding their status and results when all complete or the timeout expires, whichever happens first.
<T> TinvokeAny(Collection<? extends Callable<T>> tasks)Executes the given tasks, returning the result of one that has completed successfully (i.e., without throwing an exception), if any do.
<T> TinvokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)Executes the given tasks, returning the result of one that has completed successfully (i.e., without throwing an exception), if any do before the given timeout elapses.
booleanisShutdown()Returns true if this executor has been shut down.
booleanisTerminated()Returns true if all tasks have completed following shut down.
voidshutdown()Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
List<Runnable>shutdownNow()Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
Future<?>submit(Runnable task)Submits a Runnable task for execution and returns a Future representing that task.
<T> Future<T>submit(Runnable task, T result)Submits a Runnable task for execution and returns a Future representing that task.
<T> Future<T>submit(Callable<T> task)Submits a value-returning task for execution and returns a Future representing the pending results of the task.

1.5 参考文档:

  1. ScheduledExecutorService (Java SE 11 & JDK 11 ) (oracle.com)

  2. ExecutorService 接口介绍

  3. ScheduledExecutorService的简单使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值