简体   繁体   English

TimerService EJB多次初始化

[英]TimerService EJB initialize multiple times

In one hand I've a CronScheduler class which is meant to starts once per application an configure a TimerService. 一方面,我有一个CronScheduler类,该类旨在为每个应用程序启动一次,配置一个TimerService。
In the other hand I've a heavy task (annotated as @EJB ) which I want to call in the @timeout of the timer. 另一方面,我有一个繁重的任务(标注为@EJB ),我想在计时器的@timeout中调用它。 Note that in the timer, I create a thread which calls p.go() 请注意,在计时器中,我创建了一个调用p.go()的线程。

The code: 编码:

@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();
  }

}

The point is, the cron is initialize multiple times. 关键是,cron会被初始化多次。 The @PostConstruct code runs N times. @PostConstruct代码运行N次。 In the logs I see. 在日志中,我看到了。

Ready for: A-B-C
Ready for: A-B-C
Ready for: A-B-C

The consequences are p.go() is called multiple times. 结果是p.go()被多次调用。 Is the @singleton annotation working fine? @singleton注释工作正常吗?

Perhaps you have more than one timer running? 也许您有多个计时器在运行? I recently encountered a weird scenario where timer was set to 1k ms and the new one started before the previous one finished. 我最近遇到了一种奇怪的情况,其中将计时器设置为1k ms,而新计时器在上一个计时器完成之前启动。 Adding some kind of lock fixed it for me. 添加某种锁为我修复了它。 Maybe it's similar case. 也许是类似的情况。

You could debug and check how many threads you have active. 您可以调试并检查活动线程数。

Finally I got; 终于我得到了; it's a matter of EJB and hand-made threads. 这是EJB和手工线程的问题。 The point wasn't the Timer itself but the creation of a new thread which is not handled by the EJB magic. 关键不是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();
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM