网站建设合同违约条款,软件开发公司网站模板,wordpress 两个导航,中国菲律宾概念股Timer使用一个线程#xff0c;一个小根堆。线程执行根上的任务#xff0c;小根堆会根据执行时间戳重新调整#xff0c;根上的任务是下一个执行的任务。
DelayedQueue维护一个优先级队列#xff0c;本质也是一个数组方式的堆。任务生成时也有时间戳#xff0c;只提供存储。…Timer使用一个线程一个小根堆。线程执行根上的任务小根堆会根据执行时间戳重新调整根上的任务是下一个执行的任务。
DelayedQueue维护一个优先级队列本质也是一个数组方式的堆。任务生成时也有时间戳只提供存储。
ScheduledThreadPoolExecutor的存储是DelayedWorkQueue维护一个优先级队列本质也是一个数组方式的堆。也是任务有对应的时间戳执行后重新设置任务执行时间但是是多线程方式执行。
Spring的Scheduled底层使用的是ScheduledThreadPoolExecutor。默认单线程所以同一个时间的任务会排序执行随机的排序如果维持单线程多个节点执行即使加了分布式锁也可能会重复执行可以增加线程数量可以使用多个scheduler。https://blog.csdn.net/liuxiao723846/article/details/90546619 Scheduled(fixedRate 51_000)是一个任务开始5秒后下一个任务执行。 Scheduled(fixedDelay 51_000)是一个任务结束5秒后下一个任务执行。
上面使用堆的方式插入任务的效率是nlognlogn是因为堆调整为新的小根堆时是logn。
Quartz使用一个调度器线程遍历所有任务当前是否到了执行时间太慢。
Netty包里有HashedWheelTimer。时间轮在Dubbo定时重试RocketMQ延时消息、XXL-Job任务调度中都有使用。 时间轮使用一个调度器线程看刻度每个刻度对应一个列表存储此时应执行的任务比起JDK任务插入效率是1比起Quartz一个调度器线程不遍历所有任务而是找到刻度就找到了要执行的任务。 但是在时间刻度多但任务数量少的情况下遍历刻度反倒不如遍历任务效率低而且很多刻度上没有任务还占用空间。 所以可以使用多维度的时间轮来减少刻度比如秒级刻度一天有86400个秒使用这种任务少时不合适。可以使用一个小时级刻度加一个分钟级刻度加一个秒级刻度。 还可以以应用方向为层级构造垂直多层的时间轮一层是一个应用方向但调度时仍然是一个线程类似于IO多路复用。
参考http://it.taocms.org/01/100134.htm