请在下面找到我创建并打算用作自定义对象的类。
public class SelfExpiringObject {
private boolean expired;
// other properties
public void setValidity(final int seconds) {
new Timer().schedule(new TimerTask() {
public void run() {
expired = true;
}
}, TimeUnit.SECONDS.toMillis(seconds));
}
public boolean isExpired() {
return expired;
}
}
任何人都可以提出更好的选择吗?
想在规则引擎中使用它来处理事件。其中一个场景是收到事件时,将它们放入会话中(使用具有自失效属性的对象)。我希望他们仅按照规则中设置的有效性进入会话。一旦它们到期,它们将被从会话中删除。
答案 0 :(得分:7)
懒洋洋地计算到期时间:
private long expiryDate; // set in constructor
public boolean isExpired() {
return System.currentTimeMillis() >= expiryDate;
}
无需生成线程。
答案 1 :(得分:5)
每个Timer创建一个线程,这是一个非常昂贵的对象。我建议您只在对象中有到期时间,并有一个线程定期删除过期的对象。
public class ExpiringObject {
private long expiresMS;
// other properties
public void setValidity(final int seconds) {
expiresMS = System.currentTimeMillis() + seconds * 1000;
}
public boolean isExpired() {
return System.currentTimeMillis() >= expireMS;
}
}
监视这些项目的线程可以在Drools过期时更新。
答案 2 :(得分:3)
您可以简单地使用时间戳来代替计时器:
public class SelfExpiringObject {
private long timestamp;
private boolean expired;
// other properties
public void setValidity(final int seconds) {
timestamp = System.currentTimeMillis() + 1000 * seconds;
}
public boolean isExpired() {
if (!expired) {
expired = System.currentTimeMillis() >= timestamp;
}
return expired;
}
}
答案 3 :(得分:3)
答案 4 :(得分:2)
ScheduledExecutor
往往更健壮。isExpired
的代码可能仍会看到false
- 最简单的方法是标记变量volatile
所以你的类看起来像这样(虽然我更喜欢其他提议的方法来完全删除线程并改为使用时间戳):
public class SelfExpiringObject {
private final ScheduledExecutorService scheduler;
private volatile boolean expired = false;
// other properties
public SelfExpiringObject(ScheduledExecutorService scheduler) {
this.scheduler = scheduler;
}
public void setValidity(final int seconds) {
scheduler.schedule(new Runnable() {
public void run() {
expired = true;
}
}, seconds, TimeUnit.SECONDS);
}
public boolean isExpired() {
return expired;
}
}
创建ScheduledExecutorService:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(poolSize);