Trouble Shooting -- Commonj任务同一时间多次触发

老系统,使用了commonj做为时间和任务线程池。其中的时间管理之前系统只有单个fixed-rate的时间任务一直都运行的很好,最近系统中加入了健康监控(dropwizard healtch check),需要加多一个时间任务,结果在测试过程中出现了healtch check任务偶尔在触发点执行多次的问题,百思不得其解,读了commonj的源代码 (de.myfoo.commonj.timers.FooTimerManager.java和de.myfoo.commonj.timers.TimerExecutor.java)才大概知道问题可能是怎么回事,从代码里面我们可以看出,如果同时有2个timer task,在第一个task正在执行的时候(timer.getScheduledExecutionTime() 还没被执行到),那么waittime就会是负数,整个while循环会不停的运行,假设这个时候第二个task符合执行条件,就会被加入执行pool,如果第二个task在下一次循环的时候状态还没有改变(因为waittime是0),就会被多次加入pool,我们的系统中最多被加入了7次,都是多线程惹的祸,footimermanager完全无法预料加入pool的task什么时候改变状态,以另外线程的状态来判断任务是否在执行不可取,最后把系统的commonj改成了spring的scheduled task,简单好用。

//FooTimerManager
@Override
182 public void run() {
183
184     // while we are not stopped...
185     while (!stopped) {
186
187         long nextTime = System.currentTimeMillis() + 1000;
188
189         synchronized (this) {
190             // iterate all timers and check if the need to be executed
191             for(Iterator<TimerExecutor> iter = timers.iterator(); iter.hasNext();) {
192                 TimerExecutor timerExecutor = iter.next();
193                 FooTimer timer = timerExecutor.getTimer();
194
195                 // Added by SOSI-DCC
196                 // check if timer is cancelled
197                 if(timer.isCancelled()) {
198                     iter.remove();
199                 }
200
201                 // check if timer is expired
202                 else if(timer.isExpired() && !timerExecutor.isRunning()) {
203                     // execure timer if not suspended / suppending
204                     if(!suspended && !suspending) {
205                                                    pool.execute(timerExecutor);
206                     }
207
208                     // remove one shot timers after execution
209                     if(timer instanceof OneShotTimer) {
210                         iter.remove();
211                     }
212                 } else {
213                     // find the soonest execution time
214                     long time = timer.getScheduledExecutionTime();
215                     if(time < nextTime) {
216                         nextTime = time;
217                     }
218                 }
219             }
220
221             // count running timers that are still running
222             boolean running = false;
223             for(Iterator<TimerExecutor> iter = timers.iterator(); iter.hasNext();) {
224                 TimerExecutor timerExecutor = iter.next();
225                 if(timerExecutor.isRunning()) {
226                     running = true;
227                 }
228             }
229
230             if(suspending && !running) {
231                 suspended = true;
232             }
233
234             if(stopping && !running) {
235                 stopped = true;
236             }
237
238             // wait til next execution is due...
239             long waitTime = nextTime - System.currentTimeMillis();
240             if(waitTime > 0) {
241                 try {
242                     wait(waitTime);
243                 } catch(InterruptedException e) { // ignore
244                 }
245             }
246
247         }
248     }
249
250 }
//TimerExecutor
@Override
72  public void More ...run() {
73      running = true;
74      try {
75          // execute the timer
76          timer.execute();
77
78          // compute next execution time
79          timer.computeNextExecutionTime();
80      } catch (Exception e) {
81          // ignore
82      } finally {
83          running = false;
84          // timerManager.notifyAll();
85      }
86  }
时间: 2024-10-08 18:13:48

Trouble Shooting -- Commonj任务同一时间多次触发的相关文章

SharePoint Workflow Trouble Shooting(一)Task被锁住或者卡住

[译者按]Andy Li这篇文章,是我看过的最好的,最透彻的关于SharePoint Workflow架构的文章.通过阅读他的文章,我才清楚的了解了SharePoint Workflow的运作机制,并且在遇到问题的时候,知道如何下手查找问题.因此翻译过来,希望对Workflow的开发人员有帮助.本部分主要讲trouble shooting. 这篇博客是由Andy Li贡献的,他是SharePoint开发人员支持组的处理疑难问题的工程师.原文地址.这个关于Workflow的系列,是他贡献给社区的,

Android-First trouble shooting

进来的开发一直都很奇葩,从PC web前端到web后端再到iOS端再到Android端,每一次都是摸了点皮毛就得因为项目需求转战其他平台,想想真觉得不合适.就像从昨天其遇到的这个问题,竟然调了几个小时才确定问题. 下面废话少说了,写trouble shooting. 之前依照网上的教程已经跑通了一个demo,完成蓝牙的启动.配对.写命令以及activity的切换. 结果前两天在重新写一个程序,然后添加了前向的一些功能后,将之前写好的这些代码和XML文件添加到这个项目中,却在切换进程和打开蓝牙时都

rsyslog trouble shooting

openstack,swift的log不输出了.trouble shooting过程 , 发现我们的程序 /var/log/swift/proxy.log等总是不输出log. 因为log rsyslog控制,所以这些log应该是 rsyslog进程打开 lsof -p rsyslog 发现没有打开这些文件, 并显示一些错误信息. 重启rsyslogd进程发现下面信息 /var/lib/rsyslog/imjounral.state 不能scan. 删掉这个文件 重启rsyslogd进程 , OK

Linux 常见的trouble shooting故障排错

Linux 常见的trouble shooting故障排错 备份开机所必须运行的程序对一个运维人员来说是非常有必要的.在实际生产环境中,系统和数据基本都是安装在不同的硬盘上面,因为企业最关心的还是数据,系统崩溃了,最坏的方法就是重新安装系统,但是数据丢失了,那会直接给企业带来损失,如果系统和数据都放在同一个硬盘上面,那系统都进不去了,何谈数据.解决常见的trouble shooting,不要在系统出现故障的时候,想到的第一个就是重装系统.为解决常见的trouble shooting,首先必须先了

SharePoint Workflow Trouble Shooting(二)分析log文件

[译者按]Andy Li这篇文章,是我看过的最好的,最透彻的关于SharePoint Workflow架构的文章.通过阅读他的文章,我才清楚的了解了SharePoint Workflow的运作机制,并且在遇到问题的时候,知道如何下手查找问题.因此翻译过来,希望对Workflow的开发人员有帮助.本部分主要讲trouble shooting. 这篇博客是由Andy Li贡献的,他是SharePoint开发人员支持组的处理疑难问题的工程师.原文地址.这个关于Workflow的系列,是他贡献给社区的,

Trouble Shooting -- WebSphere 连接池不够使用的问题

之前公司有个把新创建的ABS产品发送到外部媒体验证的小项目(需要在项目中记录验证状态信息,存储在数据库中,使用openjpa做持久层实现).花了个把月的时间搞定了,产品上线运行之后(部署Websphere),爆出了一次数据库连接池不够用的问题,出现以下异常: com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException: Connection not available, Timed out waiting for 180007 我们的连接池配置

dataguard trouble shooting的相关视图

•V$DATAGUARD_STATS:显示dataguard统计信息 备库 SQL> select * from v$dataguard_stats; NAME VALUE UNIT TIME_COMPUTED DATUM_TIME -------------------------------- ------------------------- ------------------------------ ------------------------------ ------------

Mysql create constraint foreign key faild.trouble shooting method share

mysql> create table tb_test (id int(10) not null auto_increment primary key,action_id int(10) not null,error_code int(10) not null default 0,desc_key varchar(64) not null default 'audit.log.default',INDEX(action_id),constraint `FK_ACTIONID` foreign k

Ubuntu上Docker安装Trouble Shooting

(我的环境是Mint7.1,相当于Ubuntu14.04) 1,首先,根据docker.com上的安装指导来安装docker,这里就不重复了,参考: https://docs.docker.com/installation/ubuntulinux/   2,执行 $ docker version 你可能遭遇如下错误: FATA[0000] Get http:///var/run/docker.sock/v1.17/version: dial unix /var/run/docker.sock: