一方面,我有一个CronScheduler类,每个应用程序启动一次配置TimerService。
另一方面,我有一个繁重的任务(注释为@EJB
),我想在计时器的@timeout
中调用它。请注意,在计时器中,我创建了一个调用p.go()
代码:
@Singleton
@Startup
public class CronScheduler {
@EJB
Processor p;
@Resource
private TimerService timerService;
@PostConstruct
public void init() {
String h = ... // h,m ,s work fine
String m = ...
String s = ...
ScheduleExpression conf = new ScheduleExpression();
conf.hour(h);
conf.minute(m);
conf.second(s);
// I've tried with the second param (TimerConfig) enabled and disabled
timerService.createCalendarTimer(conf, new TimerConfig("msg ", false));
LOG.log(Level.INFO, ">> Ready for: " + conf.toString());
}
@Timeout
public void run() {
LOG.log(Level.INFO, "Calling the process");
Thread t = new Thread() {
@Override
public void run() {
super.run();
p.go();
}
};
t.start();
}
}
关键是,cron多次初始化。 @PostConstruct
代码运行N次。在我看到的日志中。
Ready for: A-B-C
Ready for: A-B-C
Ready for: A-B-C
后果是p.go()
被多次调用。 @singleton
注释是否正常工作?
答案 0 :(得分:0)
也许你有多个计时器在运行?我最近遇到了一个奇怪的情况,其中计时器设置为1k ms,新的计时器在前一个完成之前启动。添加某种锁定为我修复它。也许是类似的情况。
您可以调试并检查您有多少个活动线程。
答案 1 :(得分:0)
最后我得到了;它是EJB和手工制作线程的问题。关键不在于Timer本身,而是创建了一个新的线程,而这个新线程并不是由EJB魔法处理的。
@Singleton
@Startup
public class CronScheduler {
@EJB
Processor p;
@Resource
private TimerService timerService;
@PostConstruct
public void init() {
String h = ... // h,m ,s work fine
String m = ...
String s = ...
ScheduleExpression conf = new ScheduleExpression();
conf.hour(h);
conf.minute(m);
conf.second(s);
timerService.createCalendarTimer(conf, new TimerConfig("desc msg ", false));
LOG.log(Level.INFO, ">> Ready for: " + conf.toString());
}
@Timeout
public void run() {
LOG.log(Level.INFO, "Calling the process");
p.go();
}
}