2015-04-14 112 views
0

一方面,我有一個CronScheduler類,它意味着每個應用程序啓動一次配置TimerService。
另一方面,我有一個沉重的任務(註釋爲@EJB),我想在定時器的@timeout中打電話。請注意,在計時器,我創造它調用p.go()TimerService 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); 
     // 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註釋工作正常嗎?

+1

可能相關:http://stackoverflow.com/questions/9077966/postconstruct-method-called-twice-for-the-same-request和http://stackoverflow.com/questions/16796320/cdi -bean構造函數和-postconstruct所謂的海報倍 – assylias

回答

0

也許你有多個計時器在運行?我最近遇到了一個奇怪的場景,其中計時器設置爲1k ms,新計時器在前一次計時完成之前啓動。添加某種鎖定爲我解決了它。也許這是類似的情況。

您可以調試並檢查您有多少線程處於活動狀態。

0

最後我得到了;這是EJB和手工線程的問題。這一點不是定時器本身,而是創建一個不由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(); 
    } 
}