EJB Timer

  • 要么: Annotation @Schedule 或者方法前声明@Timeout
  • 要么: 在部署描述中定义timeout-method
  • 如果是使用@Schedule, Timer在一个ejb中可以支持多个,如:

@Schedule(second="*/2", minute="*",hour="*", persistent=false,info="timer1")
    public void doWork(){
        System.out.println( "Hi from the EJB timer example!" );
    }

@Schedule(second="*/1", minute="*",hour="*", persistent=false,info="timer2")
    public void doWork2(){
        System.out.println( "Hi .... 2nd timer!" );    
    }
以上分别启动了2个timer,一个每隔2秒执行一次,一个每隔1秒执行一次. 执行时container做了并发访问控制.也就是说callback方法一个时刻只能执行一个方法.

  • 如果是使用@Timeout, 也就是Programmatic Timers, callback方法有且只有一个.

All timers created via one of the TimerService timer creation methods for a particular component use a single timeout callback method. --From ejb spec 3.1 chapter 18
如前一个调用没有完成,而后面的timer过来了,在后面的timer在调用callback时会等待write lock(ejb方法默认), 如果超时就会出现如下异常, Jboss的行为, 还会retry一次,如果还是timeout,则会放弃.:

09:20:59,045 ERROR [org.jboss.as.ejb3] (EJB default - 2) JBAS014122: Error during retrying timeout for timer: [id=c2a31520-2c55-4b01-b362-d8dfdb73a2d0 timedObjectId=jboss-ejb-timer.jboss-ejb-timer.TimeoutExample auto-timer?:false persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@65886ae8 initialExpiration=Tue Mar 29 09:20:48 CST 2016 intervalDuration(in milli sec)=0 nextExpiration=null timerState=RETRY_TIMEOUT: javax.ejb.ConcurrentAccessTimeoutException: JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on org.jboss.invocation.InterceptorContext$Invocation@7c49f17f - could not obtain lock within 5000MILLISECONDS
    at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:100) [jboss-as-ejb3-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]

TimerService的createSingleActionTimer()和createIntervalTimer()

  • createSingleActionTimer

只触发一次,如果触发时等不到锁,timeout, 则如上所述,再试一次,如果还不行,直接放弃。

  • createIntervalTimer

周期性触发,到点触发发现上一个还没搞完,则直接skip,放弃了,接着等下一个,如下code

@Timeout
    public void scheduler(Timer timer) {
        System.out.println("EJB Timer: Info=" + timer.getInfo() + " " + Thread.currentThread().getName());

try {
            Thread.sleep(1000*30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

//
    @PostConstruct
    public void initialize( InvocationContext ctx ) {
        //...
        timerService.createIntervalTimer(2000, 10*1000, new TimerConfig("Single Timer #2", false));
        //....
    }

输出的log如下:
10:21:47,864 INFO  [stdout] (EJB default - 7) EJB Timer: Info=Single Timer #2 EJB default - 7

10:21:57,864 WARN  [org.jboss.as.ejb3] (EJB default - 9) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:21:57 CST 2016
10:22:07,864 WARN  [org.jboss.as.ejb3] (EJB default - 6) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:22:07 CST 2016
10:22:17,864 WARN  [org.jboss.as.ejb3] (EJB default - 8) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:22:17 CST 2016
10:22:27,865 INFO  [stdout] (EJB default - 3) EJB Timer: Info=Single Timer #2 EJB default - 3

10:22:37,864 WARN  [org.jboss.as.ejb3] (EJB default - 10) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:22:37 CST 2016
10:22:47,864 WARN  [org.jboss.as.ejb3] (EJB default - 2) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:22:47 CST 2016
10:22:57,864 WARN  [org.jboss.as.ejb3] (EJB default - 1) JBAS014143: A previous execution of timer [jboss-ejb-timer.jboss-ejb-timer.TimeoutExample 8ba38f5a-0da7-4993-8b0b-e69854f61ee4] is still in progress, skipping this overlapping scheduled execution at: Tue Mar 29 10:22:57 CST 2016

Jboss quickstart中有timer的例子。

更复杂的例子:

如果显示指定callback方法为read lock,情况如何呢?

  1. 如果上一个callback方法没有完成,这时候下一个timer(第二次timer)触发的调用过来了.
  2. 因为是read lock, 所以顺利进入到callback方法内部, 上面说的等锁而导致的timeout retry行为就不会发生.
  3. ejb container从线程池中调度一个thread过来,执行callback,因为某种原因花了很长时间.
  4. 第三次timer触发, ejb从线程池再拿一个thread,执行callback, ...
  5. 到了第11次触发(线程池数量假设为10), 无线程可用,方法阻塞,等待(注意不会timeout,因为已经进入到callback方法体)
  6. 其他ejb如果需要从线程池中启动, 发现无资源可用,也会继续等待, 注意是等待,
  7. 如果积攒的需要启动的线程越来越多, 如果前面的callback方法突然返回,哈哈,后面的线程就会疯狂的run.
  8. .....

所以搞timer, 最好不要将callback设置为read lock, 否则有可能thread leak, 试想你启动一个timer,每一秒钟执行一次, 执行的过程中hung住了, 而此时callback方法为read lock.

....

如:

//EJB A中

@Timeout
    @Lock(LockType.READ)
    public void scheduler(Timer timer) {

//Just test code, please DONT use sleep in your code!

try {
            Thread.sleep(1000*30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

}

//in initialize method

for(int i = 2; i < 20; i++)
            timerService.createSingleActionTimer(1000, new TimerConfig("Single Timer #1", false) );

//EJB B

@Schedule(second="*/2", minute="*",hour="*", persistent=false)
    public void doWork(){
        System.out.println( "Hi from the EJB timer example!" );      //这些timer会一直积攒在那里, 因为所有的线程全部被EJB A占用,没有返回.

}

所以线程池里没有线程可用会死等下去, 而如果timer调用的callback方法不会死等, 有timeout. 如果是read lock就会一直耗干线程池中的线程实例.

EJB之Timer的更多相关文章

  1. EJB Timer Service is not available. Timers for application with id 95795415990861824 will not be deleted

    delete follows:glassfish\domains\domain1\applications\ejb-timer-service-appglassfish\domains\domain1 ...

  2. EJBTimer 使用EJB提供的定时器

    一.说明 EJB提供的定时器有两种,自动定时器和自定义定时器,自动定时器设置使用简单但是扩展较为麻烦,自定义定时器有较好的扩展性. 下面的例子中是把两中方式放到了一个测试类中. 二.示例 import ...

  3. JavaEE(10) - Session EJB的依赖注入、引用及任务调度

    1. EJB依赖注入 #1. EJB开发(Net Beans创建EJB Module, 项目名称:CallHello) Hello.java package org.crazyit.service; ...

  4. Jboss EAP 6 EJB调用常见问题

    1. 调用EJB的三种方法 调用EAP 6 EJB的第一种方法,使用JBoss API,如下: Properties p = new Properties(); p.put("remote. ...

  5. C# - 计时器Timer

    System.Timers.Timer 服务器计时器,允许指定在应用程序中引发事件的重复时间间隔. using System.Timers: // 在应用程序中生成定期事件 public class ...

  6. winform 用户控件、 动态创建添加控件、timer控件、控件联动

    用户控件: 相当于自定义的一个panel 里面可以放各种其他控件,并可以在后台一下调用整个此自定义控件. 使用方法:在项目上右键.添加.用户控件,之后用户控件的编辑与普通容器控件类似.如果要在后台往窗 ...

  7. 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?

    源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...

  8. NetBean 8 创建EJB

    一. 介绍 百度了一下关于在NetBean开发环境里创建EJB的教程,没有找到好的例子,2天的调试过程,写下来帮助后人. EJB (Enterprise Java Bean) 是一套高扩展性的开发企业 ...

  9. STM32F10xxx 之 System tick Timer(SYSTICK Timer)

    背景 研究STM32F10xxx定时器的时候,无意间看到了System tick Timer,于是比较深入的了解下,在此做个记录. 正文 System tick Timer是Cotex-M内核的24位 ...

随机推荐

  1. 无密钥登录的自动脚本实现(ssh-copy-id、expect免交互输入脚本)

    感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正! 如有转载,请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...

  2. ACM/ICPC 之 混合图的欧拉回路判定-网络流(POJ1637)

    //网络流判定混合图欧拉回路 //通过网络流使得各点的出入度相同则possible,否则impossible //残留网络的权值为可改变方向的次数,即n个双向边则有n次 //Time:157Ms Me ...

  3. Angular2 组件

    1. 组件说明 Angular2 组件是构成Angular2应用程序的核心部分,Angualr2应用程序本质上来说就是一个组件树,Angular2组件一般由模块,注解,元数据以及组件类组成,实现组件类 ...

  4. 各种浏览器的Hack写法(chrome firefox ie等)

    Hack是针对不同的浏览器去写不同的CSS样式,从而让各浏览器能达到一致的渲染效果,那么针对不同的浏览器写不同的CSS CODE的过程,就叫CSS HACK,同时也叫写CSS Hack. 然后将Hac ...

  5. LeetCode——Balanced Binary Tree(判断是否平衡二叉树)

    问题: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bin ...

  6. 关闭英文拼写检查,关闭xml验证

    http://blog.sina.com.cn/s/blog_70b623e4010173ce.html eclipse里面的许多设置对于国内开发者日常使用不太适用,反而会成为干扰.既然是完全可配置的 ...

  7. GnuStep使用

    gcc -o main main1.m -I/GNUstep/System/Library/Headers -fconstant-string-class=NSConstantString -L/GN ...

  8. Javascript中的apply与call详解

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 一.方法定义 1.call 方法 语法:call([thisObj[,arg1[, arg2[, [,.arg ...

  9. 互联网+下PDA移动智能手持POS超市收银开单软件

    是一套专为中小超市.专卖店设计的收银管理软件,广泛应用于中小超市(百货商店).化妆品店.婴幼儿用品店.玩具店.保健品店.茶叶店. 电器.文具图书.手机通讯器材店等行业的中小型店面店铺.该系统具有完善的 ...

  10. 分布式缓存技术redis学习系列(二)——详细讲解redis数据结构(内存模型)以及常用命令

    Redis数据类型 与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多,常用的数据类型主要有五种:String.List.Hash.Set和Sor ...