我的必修课Java首页投稿(暂停使用,暂停投稿)

Java可自定义中断定时器的实现

2016-06-22  本文已影响808人  OneFish

Java定时器的实现一般使用的是Timer和ScheduledExecutorService

本文介绍的是ScheduledExecutorService来实现可中断定时器
我们首先看一下scheduleAtFixedRate 的javaDoc

  • If any execution of the task encounters an exception, subsequent executions are suppressed.Otherwise, the task will only terminate via cancellation or termination of the executor.

通过javaDoc可以发现需要终止task的方法有三种:

  1. 执行shutdown(),但是这个会终止整个Executor
  2. task抛出异常,在task执行到需要中断的时候,抛出异常
  3. 取消当前执行的task

执行shutdown()肯定是不合适的,通过主动抛异常的方式来中断也不好
所以使用取消当前task的方式来实现自定义中断

  1. 首先看一下scheduleAtFixedRate的源码,我们注意到这个方法返回的是ScheduledFuture<?>
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

ScheduledFuture是继承了Future的

public interface ScheduledFuture<V> extends Delayed, Future<V>

这样就可以通过Future.cancel()的方式来取消当前task实现自定义中断

  1. 初始化ScheduledExecutorService 线程池
private ScheduledExecutorService service = Executors.newScheduledThreadPool(20,new NamedThreadFactory("Schedule-Task"));
  1. 实现业务逻辑和退出条件
    实现思路是通过保存每个task的Future对象,在满足条件是,执行future.cancel()
// 当前正在执行的task合集 
private Map<String,Future> futures = new HashMap<>();
// 执行定时任务的时间间隔
private int period = 5;
private String taskPrefix ="DoSomething-Task";
public void executeTask(String id) {

    // 已有当前定时任务在执行时,删掉当前任务,然后重新启动
    if (futures.containsKey(taskPrefix+id)) {
        futures.get(taskPrefix+id).cancel(true);
        futures.remove(taskPrefix+id);
    }
    Future future = service.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            int currentNum = cacheService.getCurrentShowNum(id);
            // 满足中断task条件
            if ( /* 条件逻辑 */) {
                Future currentFuture = futures.get(taskPrefix+id);
                currentFuture.cancel(true);
                // 任务执行完成
                futures.remove(taskPrefix+id);
            } else {
                // 执行task业务逻辑
            }
        }
    },0,period, TimeUnit.MINUTES);
    futures.put(taskPrefix+id,future);
}
上一篇下一篇

猜你喜欢

热点阅读