1. 最直接的是一个方案定时任务用一个线程.然后用 Thread.sleep .
2. 最好的方案是将任务 task 化.
利用统一的线程池处理.为了实现延迟机制利用 scheduleTask delayTask.
任务完成末尾,再加入任务队列.
每次 getTask,如果第一个都没满足就阻塞.直到满足为止.
其他细节点: 1.第一次直接 run
2.利用 exchangeFIled()方法,巧妙避免 内部类 final 限制
3. 判断配置是否更新来决定是否 exchangeFIled
Runnable runnable = new Runnable() { @Override public void run() { List<String> c = null; try { c = loadServers(); boolean isDiffrent=false; for (int i = 0; i < c.size(); i++) { if (serverIps==null||!serverIps.contains(c)){ isDiffrent=true; break; } } //降低 exchange 频率,降低 filed 切换,减少垃圾生成. if (serverIps==null||isDiffrent) { exchangeIps(c); } } catch (Exception e) { logger.error("getSeverIps error",e); } finally { if (logger.isDebugEnabled()) { logger.debug("getIps:" + JsonUtil.toJson(c)); } } SchduledExecutor.scheduleSecond(this, 10); } };
the Leader-Follower pattern http://www.cs.wustl.edu/~schmidt/POSA/POSA2
jdk 里使用最小堆来实现定时器.
linux POSIX timer 的描述 使用 最小堆.
https://www.ibm.com/developerworks/cn/linux/l-cn-timers/
http://www.zte.com.cn/cndata/magazine/zte_communications/2003/5/magazine/200311/t20031127_150200.htm
http://blog.csdn.net/lizhiguo0532/article/details/6406161
对于 rocketMq 使用的是 时间轮.
改进: 多级时间轮+后台排序+ 最小堆实现方式.
天级时间轮.
当天改成小时级时间轮
当小时 改成分钟级时间轮.
当分钟改改成最小堆.
后台定时任务逐级排序.