Reputation: 4202
Please find below the class that I have created and intend to use as a self-expiring object.
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;
}
}
Any better alternative that anybody can suggest?
Want to use this in a rule engine for processing events. One of the scenarios would be when the events are received, they are put into the session (using object with self-expiring property). I want them to be in the session only as per the validity set up in the rules. Once they expire, they would be removed from the session.
Upvotes: 6
Views: 6743
Reputation: 2261
The Apache Collections PassiveExpiringMap could worth looking at.
Upvotes: 4
Reputation: 328735
ScheduledExecutor
tend to be more robust.isExpired
after the Timer has run might still see false
- the simplest thing is to mark the variable volatile
So your class could look like this (although I prefer the other proposed approach to remove the threads completely and use timestamps instead):
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;
}
}
To create a ScheduledExecutorService:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(poolSize);
Upvotes: 2
Reputation: 533670
Each Timer creates a thread and this is a very expensive object. I suggest you just have the expiry time in the object and have a thread which periodically removes expired objects.
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;
}
}
The thread which monitors these items can update Drools when it has expired.
Upvotes: 9
Reputation: 13177
Instead of a timer, you could simply use timestamps:
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;
}
}
Upvotes: 3
Reputation: 32427
Just calculate the expiry lazily:
private long expiryDate; // set in constructor
public boolean isExpired() {
return System.currentTimeMillis() >= expiryDate;
}
No need to spawn a thread.
Upvotes: 8