轮子的意义

开源框架中的“轮子”往往能带来让人惊艳的设计,在此,尝试总结轮子设计适合的场景。

经典的轮子设计

  1. dubbo定时任务时间轮
  2. Disruptor追踪序列轮

相似点

基于一个2的幂次方容量的数组,通过在其上循环往复来达成如下目标:

  • 定位下标只常数时间
  • 充分利用局部性原理
  • 用空间降低时间维度的局部竞争
  • 降低fullGC的成本

差异点

  • 槽位任务数量

dubbo的时间轮槽位仅持有一个任务管理器,具体任务通过双向链表串联,从而一个槽位实际可关联n个任务。

Disruptor的追踪序列上承载的是具体的任务实体,每一个发布的任务都是赋值,而不是新建,故实际一个槽位仅关联一个任务。

  • 驱动方式

dubbo的时间轮会按规则不断的tick+1累计,然后基于掩码计算出当前需要触发的槽位下标,进而触发该槽位关联的任务。

Disruptor的追踪序列则由生产者的发布事件&消费者的消费事件相互影响驱动。

  • 存储

dubbo的槽位是存放的任务管理者,一旦创建不会变更,也没做什么缓存行填充之类的优化,因为时间轮线程,无并发竞争,任务都是堆积在队列中,且随时间轮不断的分发给具体的槽位。

Disruptor的槽位是具体的任务引用,因为使用场合会面临大量竞争的可能性,故使用了缓存行填充技术,规避不必要的竞争。

轮子适合的场合

需要o(1)操作具体元素

需要尽可能降低fullGC的影响

容量允许2的幂次方

需要大并发竞争

程序的局部性对性能有明显影响

参考:

https://www.cse.wustl.edu/~cdgill/courses/cs6874/TimingWheels.ppt

原文地址:https://www.cnblogs.com/asfeixue/p/13805167.html