package org.buddycloud.channelserver.queue; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; public abstract class ExpiringQueueAbstract extends ConcurrentHashMap<Object, Object> { private static final long serialVersionUID = 1L; private ConcurrentHashMap<Long, ArrayList> addedTime = new ConcurrentHashMap<Long, ArrayList>(); private static final int DEFAULT_TIMEOUT = 180000; private int timeout = 0; private Timer timer; public ExpiringQueueAbstract() { super(); setTimeout(DEFAULT_TIMEOUT); } public ExpiringQueueAbstract(int timeout) { super(); setTimeout(timeout); } /** * Set the expiration timeout * * @param timeout milliseconds * @return */ public ExpiringQueueAbstract setTimeout(int timeout) { this.timeout = timeout; return this; } /** * Add object to Hash Map */ public Object put(Object key, Object value) { Long timesOut = System.currentTimeMillis() + timeout; if (false == addedTime.containsKey(timesOut)) { addedTime.put(timesOut, new ArrayList<Object>()); } addedTime.get(timesOut).add(key); return super.put(key, value); } public void expireEntries() { Iterator it = addedTime.entrySet().iterator(); Long now = System.currentTimeMillis(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry) it.next(); if (now >= (Long) pairs.getKey()) { expireValues((ArrayList<Object>) pairs.getValue()); it.remove(); } } } protected void expireValues(ArrayList<Object> values) { for (Object value : values) { expireValue(value); } } protected abstract void expireValue(Object value); public void stop() { if (null == timer) { return; } } public void start() { int period = timeout / 10; if (period < 1) { period = 1; } timer = new Timer(); timer.scheduleAtFixedRate(new QueueTimer(this), period, period); } } class QueueTimer extends TimerTask { private ExpiringQueueAbstract queue; public QueueTimer(ExpiringQueueAbstract queue) { super(); this.queue = queue; } @Override public void run() { queue.expireEntries(); } }