前言
之前字节三面被问到了如何实现一个定时任务,以及定时任务的存储,用什么数据结构相关的问题。面试当时整个人都愣住了,面试结束后关于这个问题思考了很久,也和朋友讨论过这个问题,关于数据结构我还是觉得hashmap是个不错的选择,但是其实维护一个有序的双向链表好像也有点麻烦,所以还有待考究。
目前是先完成了一个简单的定时任务,使用到的数据结构是非常简单的动态数组,后面再想想怎么去优化,另外还有一些问题是要在控制协程创建数量的同时保证每个任务都能按时完成,这是后期需要优化的。
思路
说到定时,肯定在等待时间到的这一段时间里是不能占着CPU的,同时我们要知道要等待多少时间。所以我们选择协程(线程,如果是在java语言或者其他什么语言中)睡眠来完成这个任务,当然wait也可以,两个方法选一个就行,思路都是一样的。Java的Timer底层就是使用的wait方法。
实现
package main
import (
"fmt"
"log"
"sort"
"sync"
"time"
)
// 暂时用且切片保存任务列表
var taskList = ScheduleTaskSort{
// 默认先初始化16个
// 第一个参数是长度,第二个参数是容量
tasks: make([]ScheduleTask, 0, 16),
}
// 已完成的任务列表
var finishTaskList = make([]ScheduleTask, 0, 16)
// 正在进行的任务列表
var runningTaskList = make([]ScheduleTask, 0, 16)
// 读写锁用于任务列表
var mu = sync.RWMutex{
}
// 未完成的任务数量
var taskNum = 0
// 已完成的任务数量
var finishTaskNum = 0
// 正在进行中的任务数量
var runningTaskNum = 0
type ScheduleTask struct {
// 定时时间
Time int64
// 任务
Task func()
}
type ScheduleTaskSort struct {
// 根据时间进行一个定时任务的排序
sort.Interface
tasks []ScheduleTask
}
func (s ScheduleTaskSort) Len() int {
return len(taskList.tasks)
}
func (s ScheduleTaskSort) Less(i,