【问题标题】:scheduledExecutorService, timerService and Stateless EJB on scheduled jobsscheduleExecutorService、timerService 和 Stateless EJB 上的计划作业
【发布时间】:2014-09-07 02:16:13
【问题描述】:

我正在尝试在服务器中实现一个系统,该系统将定期对数据库进行一些更新。

这里:Spawning threads in a JSF managed bean for scheduled tasks using a timer 在其他一些类似的问题中,我看到 BalusC 强烈建议使用 Stateless Beans,如果不可能的话,使用 SchedulerExecuterService 而不是 Timer。

这是我的情况。我需要一个 JSF 页面,我可以在其中配置调度间隔。即我可以将其规则从每5分钟运行一次更改为每10分钟运行一次

首先,我尝试使用@Schedule 注解,它很棒。但是,我找不到改变间隔的方法。第一个问题,是否可以像我上面所说的那样动态更改它?

我目前正在使用从无状态 Bean 的 @PostConstruct 调用的 SchedulerExecutorService。 第二个问题,Timer BalusC是不是强烈推荐使用的是EJB的TimerService?

第三个问题,我喜欢 timerService 的属性,它是: 使用 scheduleExpressiontimerConfig。 ScheduledExecutorService 有没有类似的东西?

附加问题:我在正确的轨道上吗?我想要做的事情能以更好的方式完成吗?

【问题讨论】:

    标签: java jsf timer scheduled-tasks


    【解决方案1】:

    我认为@Schedule 仅用于固定的类似 cron 的计时器,其中 EJB 容器在 EJB 启动时部署一个计时器。您显然需要更多与 JSF 页面相关的动态调度。

    如果您在完整的 Java EE 6 配置文件上运行,为什么不使用带有无状态会话 EJB 的 TimerService,如下所示:

    @Stateless
    public class JobSchedulerBean {
        @Resource
        private TimerService timerService;
    
        // @PostConstruct
        public void initTimer() {
            // set initial timer
            ScheduleExpression sch = new ScheduleExpression();
            // set cron expression into sch
            timerService.createCalendarTimer(sch, new TimerConfig("myTimer", false));
        }
    
        public void rescheduleTimer(int interval) {
            // get timer from timer service
            for (Timer timer : timerService.getTimers()) {
                if (timer != null && timer.getInfo().equals("myTimer")) {
                    timer.cancel();
                }
            }
            // schedule new timer, like in initTimer() method
        }
    
        @Timeout
        public void timeout(Timer timer) {
            // do the job
        }
    }
    

    编辑:

    @ManagedBean(eager=true)
    @ApplicationScoped
    public class JobRunner {
        private ScheduledExecutorService scheduler;
        private static final int POOL_SIZE = 1;
    
        ScheduledFuture<?> runHandle;
    
        @PostConstruct
        public void init() {
            scheduler = Executors.newScheduledThreadPool(POOL_SIZE);
            // set initial expiry to 5 minutes after 5 minutes delay
            runHandle = scheduler.scheduleAtFixedRate(new MyJob(), 5, 5, TimeUnit.MINUTES);
        }
    
        @PreDestroy
        public void destroy() {
            scheduler.shutdownNow();
        }
    
        public void reschedule(int newDelay) {
            // cancel old timer, but do not interrupt it
            runHandle.cancel(false);
            runHandle = scheduler.scheduleAtFixedRate(new MyJob(), newDelay, newDelay, TimeUnit.MINUTES);
        }
    }
    
    public class MyJob implements Runnable {
        public void run() { 
            // do the job
        }
    }
    

    【讨论】:

    • 在很多与我分享上述链接类似的帖子中,我看到人们建议 SchedulerExecutorService 这就是我问的原因。第二个和第三个问题
    • @xtrapolate 不适用于 ScheduledExecutorService,但我看到它通过 ScheduledFuture 对象提供了类似的功能:docs.oracle.com/javase/7/docs/api/java/util/concurrent/…
    • 谢谢。 eager=true 有什么用?
    • 表示这个无状态bean是被热切加载的,意思是在启动时被实例化。与 eager=false 相对,当 bean 在第一次使用时被实例化。
    • 附注请注意,这里不需要@LocalBean。这仅在您希望 bean 公开无接口视图时使用,但由于您未实现任何接口,因此默认情况下您已经获得了这样的视图。
    猜你喜欢
    • 2023-03-12
    • 2015-12-05
    • 2016-08-27
    • 2013-03-02
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多