TimerService EJB初始化多次

时间:2015-04-14 07:47:48

标签: java multithreading java-ee ejb wildfly-8

一方面,我有一个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注释是否正常工作?

2 个答案:

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