通过扩展 PriorityBlockingQueue 的 take() 实现任务定时触发
来源:互联网 发布:韩庚偷电脑知乎 编辑:程序博客网 时间:2024/05/17 01:37
考虑这样一种情况:在一个系统中,前台可以发送一系列任务给后台执行,且任务具有定时的特性,对定时的处理,要求在后台处理,也就是说,前台不关心任务的开始i时间,只负责发送任务,后台在接收到任务之后,要判断任务的开始时间,如果开始时间没有到,需要将任务放入一个队列中,然后等待任务开始时间到了再将其取出执行。
对于这样的问题,可以采用定时器来处理:对于每一个开始时间没有到的任务,为其启动一个定时器,定时触发任务执行。但这种处理方式有两个问题:1.任务如果很多,为每个任务开启专用的定时器,必然会增加程序的复杂性和系统的负载。2.每个定时器对应一个线程,而在上面的情况下,显然最好是不要用多线程去处理的,考虑下在什么情况下适合用多线程,就会明白为什么了。
其实,对于上面的问题,可以通过扩展 PriorityBlockingQueue 的 take() 方法来完成功功能。
在 PriorityBlockingQueue 队列中没有元素的情况下,调用其 take() 方法,会阻塞,直到有元素可被取出,或者被中断。我们可以将上面提到的具有定时特殊性的任务,按照开始时间的顺序:开始时间早的,存放在 PriorityBlockingQueue 队列中的前面,开始时间迟的,存放在后面,然后重写 take()方法,重写之后,当 take()方法被调用时,即使队列中有元素,也不会立刻将其返回,而是阻塞等待队列中最前面(最前面的一定是开始时间最早的任务)的任务开始时间到,才会将其返回。
为达到上面的目的,必须解决以下几个问题:
<1>. 如何实现将开始时间早的任务放在队列的前面,开始时间晚的任务,放在队列的后面?
<2>. take()方法内部,如何实现上面期望的功能(任务开始时间到才被返回)?
第一个问题比较容易解决:PriorityBlockingQueue 本身就是一个优先级队列,可以根据开始时间自定义任务的优先级,为此需让任务继承 Comparable 接口,然后重写其compareTo()方法即可。
第二个问题,可以在 take() 方法内部启一个监控线程,监视开始时间最早的任务,待其开始时间到了,再将其返回。这里存在一个问题:在监视开始时间最早任务的过程中,如果有开始时间更早的任务到来,该如何处理?显然,此时需要将监控线程打断,让它去监控这个更早的任务,显然 offer() 方法也需要被重写。
具体的代码实现就不贴了。
- 通过扩展 PriorityBlockingQueue 的 take() 实现任务定时触发
- 通过Spring实现定时任务
- 通过Quartz实现定时任务
- 定时任务高效触发
- 定时任务高效触发
- 定时任务高效触发
- 定时任务触发多次
- nova中通过FixedIntervalLoopingCall实现的定时任务
- 定时任务的实现
- java 编程思想中的PriorityBlockingQueue 部分里对PrioritizedTask的排序没有显式调用collection的sort方法。而是通过take时做的这个动作
- 【JAVA】通过注解实现定时任务
- linux定时任务未触发
- Spring 解决Quartz定时任务被触发两次的问题
- 常用Quartz定时任务触发的cron表达式
- Java定时任务的实现
- Java定时任务的实现
- Java定时任务的实现
- Java定时任务的实现
- 计算机算法
- 在IIS上如何发布HTTPS网站,SSL安全服务配置
- java_Switch
- VC对话框的关闭按钮 调用函数的过程
- substr
- 通过扩展 PriorityBlockingQueue 的 take() 实现任务定时触发
- 行列转换
- 数据库restricted、quiesce和suspend三种模式
- dataReader 与dataSet
- linux 进程学习体会——fork()
- orcal入门详解
- 2011中国物联网优秀应用案例汇编 案例目录
- 序列化存取实现java对象深度克隆
- 三天打鱼,两天晒网