我不熟悉java中的线程,所以我正在处理这个问题:我有一个包含一些对象的单例对象(比如说会话),每个对象都有一个持续时间,所以这意味着经过一些时间一个对象被认为已过期,因此需要从(一个池 - 单个列表中)单例中删除它。为此,我决定让一个线程每隔5分钟(或10分钟或其他)检查并清理单例类中的所有会话。如何实现这样的功能,避免任何可能的死锁和/或耗时的块。先感谢您。
答案 0 :(得分:3)
我不会那样实现它。相反,我会在向池中询问会话时删除超时会话(但每次获取时都不需要)。这是BTW,你可以使用的Guava's CacheBuilder所做的是什么,因为它很简单,经过测试并提供了有用的功能。
如果你真的想这样,那么你应该使用ConcurrentMap或ConcurrentList,并使用single-thread ScheduledExecutorService,它会唤醒遍历列表并每隔X分钟删除一次旧会话。
答案 1 :(得分:2)
您是否可以选择使用预先存在的内存缓存解决方案而不是自己编写? 如果是的话,你可以查看Google Guava,它提供了一个缓存解决方案等等。
答案 2 :(得分:2)
Runnable cleaner = new Runnable() {
public void run() { /* remove expired objects here */
//Using get method check whether object is expired
}
};
Executors.newScheduledThreadPool(1)
.scheduleWithFixedDelay(cleaner, 0, 30, TimeUnit.SECONDS);
答案 3 :(得分:2)
我同意@quaylar(+1),如果可以,请使用现有的缓存技术。
但是,如果不能,则一种解决方案是使用java.util.Timer。用第一个会话对象到期的时间初始化它并使其进入睡眠状态。然后,在它唤醒时,让它删除你的会话对象并将其重置为下一个到期时间。让java处理时序方面。
答案 4 :(得分:1)
你可以这样做:我假设你的单例对象的类被称为单例,所以你有这样的东西(它不是完美的代码)
public class Singleton {
List<Objects> singletonList = Collections.synchronizedList(new ArrayList<Objects>);
}
public class RemoveExpiredItemsThread implements Runnable {
private Singleton singletonReference;
private int sleepTime = 5*60*1000;
// the constructor
// then the run method which is something like this
public void run() {
while(done == false) {
Thread.sleep(sleepTime);
singletonReference.removeItem();
}
}
}