java70行代码手搓定时任务

感谢学java的生生提供的视频,让我能够速成部分实践八股,弥补了我没有好好看和学习国外CS课程的缺憾

现在有一个Main函数,我们要实现里面scheduleService方法(就是实现@Schedule注解),让main函数正常实习

package tech.insight;

/**
 * @author gongxuanzhangmeit@gmail.com
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        ScheduleService scheduleService = new ScheduleService();
        scheduleService.schedule(() -> {
            System.out.println(1);
        }, 1000);

        Thread.sleep(1000);
        System.out.println("添加一个每200毫秒打印一个2的定时任务");
        scheduleService.schedule(() -> {
            System.out.println(2);
        }, 200);
    }
}
package tech.insight;

/**
 * @author gongxuanzhangmelt@gmail.com
 */
public class ScheduleService {

    void schedule(Runnable task, long delay) {
        // TODO
    }
}

这是一个新的工程。我们创建了一个类,这个类有一个函数 `schedule`,它有两个参数:第一个是一个任务(task),第二个是一个延迟时间(delay),单位是毫秒。每隔这么多毫秒,我们会让这个任务自动执行一次。一般来说这里可以加一个 `TimeUnit`,但我们默认使用毫秒。

我们可以先写一个“慢函数”,这个慢函数直接调用某个方法,比如打印一个“1”。我们希望它每隔100毫秒打印一次“1”。当然,在主函数中,我们不能阻塞主线程。因此,我们在主函数里先睡眠一秒,然后添加一个每200毫秒打印一次“2”的定时任务。也就是说,我们在一秒之后,再添加一个每200毫秒打印“2”的任务。

接下来我们要实现 `schedule` 方法,使得这个“慢函数”能够正常运行。

首先思考一个问题:这个任务是由谁来执行的?我们可以随便定义一个线程池,无所谓。问题是,如何用线程池去执行一个带延迟的任务? 最直观的想法就是新建一个线程池线程,让他按照要求sleep那么几秒,但是有问题:下一次什么时候能执行?目前这个任务只能执行一次,也没有延迟。我们能不能简单粗暴地让线程先 `sleep(delay)` 毫秒,然后直接调用 `task.run()`?其实是可以的,但这会带来几个问题。

void schedule(Runnable task, long delay) {
    ExecutorService executorService = Executors.newFixedThreadPool(6);
    executorService.execute(() -> {
        Thread.sleep(delay);
        task.run();
    });
}

第一个问题是:下一次什么时候执行?我们可以写一个死循环,在任务执行完后再次睡眠 `delay` 时间,然后继续执行。但这样又引出另一个问题:如果我们使用的线程池只有六个线程,那么最多只能同时处理六个任务。当用户第七次调用 `schedule` 时,线程池就会耗尽,无法提交新任务,显然这不符合我们的需求。

所以我们需要一个更好的设计思路。设想有一个组件,它可以在指定的时间点自动把任务提交到线程池中,而不是在调用 `schedule` 的时候立即提交。换句话说,如果有一个组件叫“触发器”(Trigger),它负责等待合适的时间,然后把任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值