ejb 3.1中的定时服务 - 调度超时问题

Gre*_*reg 5 java schedule timer glassfish

我用@Singleton,@ Schedudu和@Timeout注释创建了一个简单的例子来试试它们是否可以解决我的问题.

场景是这样的:EJB每5秒调用一次'check'函数,如果满足某些条件,它将创建单个动作计时器,以异步方式调用一些长时间运行的进程.(这是一种队列实现类型的东西).然后它继续检查,但是在长时间运行的过程中,它不会启动另一个.

下面是我提出的代码,但是这个解决方案不起作用,因为它看起来像我正在制作的异步调用实际上阻止了我的@Schedule方法.

@Singleton
@Startup
public class GenerationQueue {

    private Logger logger = Logger.getLogger(GenerationQueue.class.getName());

    private List<String> queue = new ArrayList<String>();

    private boolean available = true;

    @Resource
    TimerService timerService;

    @Schedule(persistent=true, minute="*", second="*/5", hour="*")
    public void checkQueueState() {

        logger.log(Level.INFO,"Queue state check: "+available+" size: "+queue.size()+", "+new Date());

        if (available) {

            timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false));
        }

    }

    @Timeout
    private void generateReport(Timer timer) {

        logger.info("!!--timeout invoked here "+new Date());

        available = false;

        try {

            Thread.sleep(1000*60*2); // something that lasts for a bit

        } catch (Exception e) {}

        available = true;

        logger.info("New report generation complete");

    }
Run Code Online (Sandbox Code Playgroud)

我在这里失踪了什么,或者我应该尝试不同的方法?欢迎任何想法:)

使用Glassfish 3.0.1最新版本进行测试 - 忘了提及

Bre*_*ail 11

单例的默认@ConcurrencyManagement是ConcurrencyManagementType.CONTAINER,默认@Lock为LockType.WRITE.基本上,这意味着每个方法(包括generateReports)都使用synchronized关键字进行有效标记,这意味着checkQueueState将在generateReport运行时阻塞.

考虑使用ConcurrencyManagement(ConcurrencyManagementType.BEAN)或@Lock(LockType.READ).如果这两个建议都没有帮助,我怀疑你发现了一个Glassfish漏洞.

顺便说一句,你可能想要persistent = false,因为你可能不需要保证checkQueueState方法每5秒触发一次,即使服务器处于脱机状态.换句话说,当您将服务器重新联机时,您可能不需要容器来触发"追赶".