mirror of https://github.com/apache/activemq.git
resolve AMQ-2005, Scheduler is now referenced by its users such that it cannot be gc'ed during normal operation
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@718931 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2ffb1a6782
commit
2b2b35e757
|
@ -93,7 +93,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
public class ActiveMQMessageConsumer implements MessageAvailableConsumer, StatsCapable, ActiveMQDispatcher {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(ActiveMQMessageConsumer.class);
|
||||
|
||||
protected static final Scheduler scheduler = Scheduler.getInstance();
|
||||
protected final ActiveMQSession session;
|
||||
protected final ConsumerInfo info;
|
||||
|
||||
|
@ -969,7 +969,7 @@ public class ActiveMQMessageConsumer implements MessageAvailableConsumer, StatsC
|
|||
|
||||
if (redeliveryDelay > 0) {
|
||||
// Start up the delivery again a little later.
|
||||
Scheduler.executeAfterDelay(new Runnable() {
|
||||
scheduler.executeAfterDelay(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
if (started.get()) {
|
||||
|
|
|
@ -148,6 +148,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
|||
}
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(ActiveMQSession.class);
|
||||
protected static final Scheduler scheduler = Scheduler.getInstance();
|
||||
|
||||
protected int acknowledgementMode;
|
||||
protected final ActiveMQConnection connection;
|
||||
|
@ -779,7 +780,7 @@ public class ActiveMQSession implements Session, QueueSession, TopicSession, Sta
|
|||
for (int i = 0; i < redeliveryCounter; i++) {
|
||||
redeliveryDelay = redeliveryPolicy.getRedeliveryDelay(redeliveryDelay);
|
||||
}
|
||||
Scheduler.executeAfterDelay(new Runnable() {
|
||||
scheduler.executeAfterDelay(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
((ActiveMQDispatcher)md.getConsumer()).dispatch(md);
|
||||
|
|
|
@ -53,6 +53,8 @@ import org.apache.commons.logging.LogFactory;
|
|||
public abstract class PrefetchSubscription extends AbstractSubscription {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(PrefetchSubscription.class);
|
||||
protected static final Scheduler scheduler = Scheduler.getInstance();
|
||||
|
||||
protected PendingMessageCursor pending;
|
||||
protected final List<MessageReference> dispatched = new CopyOnWriteArrayList<MessageReference>();
|
||||
protected int prefetchExtension;
|
||||
|
@ -109,7 +111,7 @@ public abstract class PrefetchSubscription extends AbstractSubscription {
|
|||
dispatchPending();
|
||||
}
|
||||
if (pull.getTimeout() > 0) {
|
||||
Scheduler.executeAfterDelay(new Runnable() {
|
||||
scheduler.executeAfterDelay(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
pullTimeout(dispatchCounterBeforePull);
|
||||
|
|
|
@ -42,7 +42,8 @@ import org.apache.activemq.thread.Scheduler;
|
|||
public class TimedSubscriptionRecoveryPolicy implements SubscriptionRecoveryPolicy {
|
||||
|
||||
private static final int GC_INTERVAL = 1000;
|
||||
|
||||
protected static final Scheduler scheduler = Scheduler.getInstance();
|
||||
|
||||
// TODO: need to get a better synchronized linked list that has little
|
||||
// contention between enqueuing and dequeuing
|
||||
private final List<TimestampWrapper> buffer = Collections.synchronizedList(new LinkedList<TimestampWrapper>());
|
||||
|
@ -90,11 +91,11 @@ public class TimedSubscriptionRecoveryPolicy implements SubscriptionRecoveryPoli
|
|||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
Scheduler.executePeriodically(gcTask, GC_INTERVAL);
|
||||
scheduler.executePeriodically(gcTask, GC_INTERVAL);
|
||||
}
|
||||
|
||||
public void stop() throws Exception {
|
||||
Scheduler.cancel(gcTask);
|
||||
scheduler.cancel(gcTask);
|
||||
}
|
||||
|
||||
public void gc() {
|
||||
|
|
|
@ -75,6 +75,7 @@ public class AsyncDataManager {
|
|||
public static final int PREFERED_DIFF = 1024 * 512;
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AsyncDataManager.class);
|
||||
protected static Scheduler scheduler = Scheduler.getInstance();
|
||||
|
||||
protected final Map<WriteKey, WriteCommand> inflightWrites = new ConcurrentHashMap<WriteKey, WriteCommand>();
|
||||
|
||||
|
@ -191,7 +192,7 @@ public class AsyncDataManager {
|
|||
cleanup();
|
||||
}
|
||||
};
|
||||
Scheduler.executePeriodically(cleanupTask, DEFAULT_CLEANUP_INTERVAL);
|
||||
scheduler.executePeriodically(cleanupTask, DEFAULT_CLEANUP_INTERVAL);
|
||||
}
|
||||
|
||||
public void lock() throws IOException {
|
||||
|
@ -326,7 +327,7 @@ public class AsyncDataManager {
|
|||
if (!started) {
|
||||
return;
|
||||
}
|
||||
Scheduler.cancel(cleanupTask);
|
||||
scheduler.cancel(cleanupTask);
|
||||
accessorPool.close();
|
||||
storeState(false);
|
||||
appender.close();
|
||||
|
|
|
@ -84,6 +84,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
public class AMQPersistenceAdapter implements PersistenceAdapter, UsageListener, BrokerServiceAware {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(AMQPersistenceAdapter.class);
|
||||
private static final Scheduler scheduler = Scheduler.getInstance();
|
||||
private final ConcurrentHashMap<ActiveMQQueue, AMQMessageStore> queues = new ConcurrentHashMap<ActiveMQQueue, AMQMessageStore>();
|
||||
private final ConcurrentHashMap<ActiveMQTopic, AMQTopicMessageStore> topics = new ConcurrentHashMap<ActiveMQTopic, AMQTopicMessageStore>();
|
||||
private static final String PROPERTY_PREFIX = "org.apache.activemq.store.amq";
|
||||
|
@ -271,14 +272,14 @@ public class AMQPersistenceAdapter implements PersistenceAdapter, UsageListener,
|
|||
checkpoint(false);
|
||||
}
|
||||
};
|
||||
Scheduler.executePeriodically(periodicCheckpointTask, getCheckpointInterval());
|
||||
scheduler.executePeriodically(periodicCheckpointTask, getCheckpointInterval());
|
||||
periodicCleanupTask = new Runnable() {
|
||||
|
||||
public void run() {
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
Scheduler.executePeriodically(periodicCleanupTask, getCleanupInterval());
|
||||
scheduler.executePeriodically(periodicCleanupTask, getCleanupInterval());
|
||||
|
||||
if (lockAquired && lockLogged) {
|
||||
LOG.info("Aquired lock for AMQ Store" + getDirectory());
|
||||
|
@ -301,8 +302,8 @@ public class AMQPersistenceAdapter implements PersistenceAdapter, UsageListener,
|
|||
}
|
||||
this.usageManager.getMemoryUsage().removeUsageListener(this);
|
||||
synchronized (this) {
|
||||
Scheduler.cancel(periodicCheckpointTask);
|
||||
Scheduler.cancel(periodicCleanupTask);
|
||||
scheduler.cancel(periodicCheckpointTask);
|
||||
scheduler.cancel(periodicCleanupTask);
|
||||
}
|
||||
Iterator<AMQMessageStore> queueIterator = queues.values().iterator();
|
||||
while (queueIterator.hasNext()) {
|
||||
|
|
|
@ -83,6 +83,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
*/
|
||||
public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEventListener, UsageListener, BrokerServiceAware {
|
||||
|
||||
protected static final Scheduler scheduler = Scheduler.getInstance();
|
||||
private static final Log LOG = LogFactory.getLog(JournalPersistenceAdapter.class);
|
||||
|
||||
private final Journal journal;
|
||||
|
@ -230,7 +231,7 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
|
|||
recover();
|
||||
|
||||
// Do a checkpoint periodically.
|
||||
Scheduler.executePeriodically(periodicCheckpointTask, checkpointInterval / 10);
|
||||
scheduler.executePeriodically(periodicCheckpointTask, checkpointInterval / 10);
|
||||
|
||||
}
|
||||
|
||||
|
@ -241,7 +242,7 @@ public class JournalPersistenceAdapter implements PersistenceAdapter, JournalEve
|
|||
return;
|
||||
}
|
||||
|
||||
Scheduler.cancel(periodicCheckpointTask);
|
||||
scheduler.cancel(periodicCheckpointTask);
|
||||
|
||||
// Take one final checkpoint and stop checkpoint processing.
|
||||
checkpoint(true, true);
|
||||
|
|
|
@ -21,25 +21,33 @@ import java.util.Timer;
|
|||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Singelton, references maintained by users
|
||||
* @version $Revision$
|
||||
*/
|
||||
public final class Scheduler {
|
||||
public final class Scheduler {
|
||||
|
||||
private final Timer CLOCK_DAEMON = new Timer("ActiveMQ Scheduler", true);
|
||||
private final HashMap<Runnable, TimerTask> TIMER_TASKS = new HashMap<Runnable, TimerTask>();
|
||||
private static Scheduler instance;
|
||||
|
||||
static {
|
||||
instance = new Scheduler();
|
||||
}
|
||||
|
||||
|
||||
public static final Timer CLOCK_DAEMON = new Timer("ActiveMQ Scheduler", true);
|
||||
private static final HashMap<Runnable, TimerTask> TIMER_TASKS = new HashMap<Runnable, TimerTask>();
|
||||
|
||||
private Scheduler() {
|
||||
}
|
||||
|
||||
public static synchronized void executePeriodically(final Runnable task, long period) {
|
||||
public static Scheduler getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public synchronized void executePeriodically(final Runnable task, long period) {
|
||||
TimerTask timerTask = new SchedulerTimerTask(task);
|
||||
CLOCK_DAEMON.scheduleAtFixedRate(timerTask, period, period);
|
||||
TIMER_TASKS.put(task, timerTask);
|
||||
}
|
||||
|
||||
public static synchronized void cancel(Runnable task) {
|
||||
public synchronized void cancel(Runnable task) {
|
||||
TimerTask ticket = TIMER_TASKS.remove(task);
|
||||
if (ticket != null) {
|
||||
ticket.cancel();
|
||||
|
@ -47,13 +55,12 @@ public final class Scheduler {
|
|||
}
|
||||
}
|
||||
|
||||
public static void executeAfterDelay(final Runnable task, long redeliveryDelay) {
|
||||
public void executeAfterDelay(final Runnable task, long redeliveryDelay) {
|
||||
TimerTask timerTask = new SchedulerTimerTask(task);
|
||||
CLOCK_DAEMON.schedule(timerTask, redeliveryDelay);
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
public void shutdown() {
|
||||
CLOCK_DAEMON.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue