V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tctc4869
V2EX  ›  Java

使一个类型的每一个实例创建都带有定时引发事件的功能,这个是如何实现的?

  •  
  •   tctc4869 · 2020-11-24 14:45:46 +08:00 · 1934 次点击
    这是一个创建于 1492 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想让我自定义的 java 类,在被创建后,有定时功能。每个对象在被创建后的每过一段时间引发一个事件,事件参数有类的实例,在事件内编写代码进行处理,定时引发的事件可以设置只引发一次,也可以设置多次引发事件。也可以设置终止引发事件。

    比如定时时间是 8 秒,有一个类,该类有两个实例,前一个在第 1 秒时创建,后一个在第 5 秒时被创建,前一个实例会在第 9 秒,引发一个事件,后一个会在第 13 秒引发一个事件,这只是只引发一次的情况,如果是多次引发,那么前一个会在一分钟内的 9 秒,17 秒、25 秒、33 秒、41 秒、49 秒、57 秒,各引发一个事件。后一个实例会在一分钟内的 13 秒、21 秒、29 秒、37 秒、45 秒、53 秒,各引发一个事件。

    实际的应用的话,比如 Session 的过期功能,每一个 session 在产生后的过期引发的事件,从 session 缓存里移除了,又比如 netty 里每一个连接的心跳超时引发的事件。

    这个在思路和原理上是如何实现的?有现成框架么?

    第 1 条附言  ·  2020-11-24 16:32:09 +08:00
    在达到“类实例创建时间+设置的定时时间“的时间后会触发事件,这个思路具体是如何实现的?
    14 条回复    2020-11-24 19:25:24 +08:00
    opengps
        1
    opengps  
       2020-11-24 15:01:24 +08:00
    类里有私有变量定时器
    构造函数里有定时器启动
    xizismile
        2
    xizismile  
       2020-11-24 15:35:02 +08:00 via Android
    你想偏了,你应该在对象失效被清除之后,插一段触发事件的逻辑
    aop 了解一下
    gotonull
        3
    gotonull  
       2020-11-24 15:37:19 +08:00
    构造函数中起定时器
    GM
        4
    GM  
       2020-11-24 15:40:48 +08:00   ❤️ 2
    你这个需求是很奇怪的,很可能不是你真实的需求。

    我的感觉,你所描述的像是初学者想要达成一个目标,但是并不知道这个目标怎么做比较合理,所以能做的就是用自己当前所掌握的知识、工具来设计了看起来能达成目标的一个方案(也就是你所提出的对象创建后的定时事件),然后再去问大家怎么实现这个方案。

    建议描述你的真实需求,让大家提出更好的解决方案。
    1wlinesperday
        5
    1wlinesperday  
       2020-11-24 15:49:19 +08:00
    我感觉做一个抽象,假设就叫 DelayedFunc 接口吧,让每个类型都实现这个接口。
    每个类型都实现两个接口方法 分别返回一个时间戳和待调用的 Function 。

    然后有个 DelayedFuncManager 统一管理这些对象就可以了。

    你只需要添加实例到这 manager 就行了,manager 内部可以用堆来管理它们,感觉也比较清晰。
    tctc4869
        6
    tctc4869  
    OP
       2020-11-24 16:07:48 +08:00
    @opengps
    @gotonull
    每起一个定时器会开启一个线程把?
    tctc4869
        7
    tctc4869  
    OP
       2020-11-24 16:19:42 +08:00
    @1wlinesperday 抽象类接口不是问题,主要问题是怎么准确延时触发事件,这个我不知道代码思路是怎样实现的。
    @xizismile
    wysnylc
        8
    wysnylc  
       2020-11-24 16:27:33 +08:00   ❤️ 1
    @GM #4 绝逼是
    raiz
        9
    raiz  
       2020-11-24 16:36:50 +08:00
    共享一个定时器,每一个实例只记录过期时间
    securityCoding
        10
    securityCoding  
       2020-11-24 16:41:22 +08:00
    @tctc4869 准确的延时执行,关键字搜索:时间轮
    across
        11
    across  
       2020-11-24 16:42:25 +08:00
    如果 [Subscribe] [Observer] 模式知道就没有困难吧。
    事件有个统一管理器 Mgr,类构造函数时向其注册事件,Mgr 内部定时检查事件更新时机,到了调用下不就好了。
    huifer
        12
    huifer  
       2020-11-24 16:44:12 +08:00
    event 开发
    tctc4869
        13
    tctc4869  
    OP
       2020-11-24 16:59:14 +08:00
    hebin
        14
    hebin  
       2020-11-24 19:25:24 +08:00 via iPhone
    简单的方法可以 manager 内部用时间戳来创建一个堆,一个线程不断取出最小的(也就是最近要过期的那个)取出来用注册的时间戳做判断,到了就执行,没到在放回去就可以了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:57 · PVG 10:57 · LAX 18:57 · JFK 21:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.