Реализация потока монитора в Java
Ну, я не знаком с потоками в Java, поэтому я имею дело с этой проблемой: у меня есть одноэлементный объект, который содержит некоторые объекты (скажем, сеансы), и каждый объект имеет продолжительность времени, так что это означает, что через некоторое время один объект считается истекшим, поэтому его необходимо удалить из (пул - список в синглтоне) синглтона. Для этого я решил создать поток, который проверяет каждые 5 минут (или 10 минут или что-то еще) и очищает весь сеанс в классе синглтона. Как я могу реализовать такую функциональность, избегая любых возможных тупиковых и / или занимающих много времени блоков. Заранее спасибо.
5 ответов
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);
Я бы так не реализовал. Вместо этого я бы удалил тайм-аут сеансов, когда сеанс запрашивается в пуле (хотя не обязательно при каждом получении). Это, кстати, то, что делает CacheBuilder от Guava, который вы можете использовать, поскольку он прост, протестирован и предоставляет полезные функции.
Если вы действительно хотите пойти по этому пути, то вам, вероятно, следует использовать ConcurrentMap или ConcurrentList и использовать однопотоковый ScheduledExecutorService, который будет вызывать итерацию по списку и удалять старые сеансы каждые X минут.
Можно ли использовать ранее существующее решение для кэширования в памяти вместо того, чтобы писать свое? Если да, вы можете проверить Google Guava, который предлагает Caching-решение среди многих других вещей.
Я согласен с @quaylar (+1), используйте существующую технологию кэширования, если можете.
Если вы не можете, однако, одним из решений является использование java.util.Timer. Инициализируйте его временем до истечения срока действия первого объекта сеанса и переведите его в спящий режим. Затем, при пробуждении, удалите объект сеанса и сбросьте его со временем до следующего срока действия. Позвольте Java обрабатывать аспекты синхронизации.
Ну, вы можете сделать что-то вроде этого: я предполагаю, что класс для вашего одноэлементного объекта называется singleton, поэтому у вас есть что-то вроде этого (это не идеальный код)
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();
}
}
}