User: ejort
Date: 02/04/20 04:37:50
Added: src/main/org/jboss/mx/util RunnableScheduler.java
SchedulableRunnable.java
Log:
Improved Timer and Monitor Services
Revision Changes Path
1.1 jmx/src/main/org/jboss/mx/util/RunnableScheduler.java
Index: RunnableScheduler.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.mx.util;
import java.util.Iterator;
import java.util.TreeSet;
/**
* A runnable scheduler.<p>
*
* The scheduler needs to be started to do real work. To add work to the
* scheduler, create a SchedulableRunnable and set the scheduler. When
* the next run has passed the work is performed.
*
* @see SchedulableRunnable
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a>.
* @version $Revision: 1.1 $
*/
public class RunnableScheduler
implements Runnable
{
// Attributes ----------------------------------------------------
/**
* The runnables to schedule
*/
private TreeSet runnables = new TreeSet();
/**
* The thread pool used to process the runnables.
*/
private ThreadPool threadPool;
/**
* The controller thread.
*/
private Thread controller = null;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
/**
* Constructs a new runnable scheduler.
*/
public RunnableScheduler()
{
}
/**
* Start the scheduler
*/
public synchronized void start()
{
if (controller != null)
return;
controller = new Thread(this);
controller.start();
}
/**
* Stop the scheduler
*/
public synchronized void stop()
{
if (controller == null)
return;
controller.interrupt();
controller = null;
}
/**
* Run the scheduler
*/
public void run()
{
// Start the threadpool
threadPool = new ThreadPool();
threadPool.setActive(true);
try
{
// Do outstanding work until stopped
while (true)
{
try
{
runOutstanding();
waitOutstanding();
}
catch (InterruptedException weAreDone)
{
break;
}
}
}
finally
{
// Stop the thread pool
threadPool.setActive(false);
threadPool = null;
}
}
// Public --------------------------------------------------------
// X Implementation ----------------------------------------------
// Y Overrides ---------------------------------------------------
// Protected -----------------------------------------------------
// Package -------------------------------------------------------
/**
* Add a schedulable runnable
*
* @param runnable the runnable to add
*/
synchronized void add(SchedulableRunnable runnable)
{
runnables.add(runnable);
notifyAll();
}
/**
* Remove a schedulable runnable
*
* @param runnable the runnable to add
*/
synchronized void remove(SchedulableRunnable runnable)
{
runnables.remove(runnable);
}
/**
* Check whether the scheduler contains a runnable
*
* @param runnable the runnable to check
* @return true when the runnable is present, false otherwise
*/
synchronized boolean contains(SchedulableRunnable runnable)
{
return runnables.contains(runnable);
}
// Private -------------------------------------------------------
/**
* Run all outstanding runnables, they are in date order
*/
private synchronized void runOutstanding()
{
long current = System.currentTimeMillis();
Iterator iterator = runnables.iterator();
while (iterator.hasNext())
{
SchedulableRunnable next = (SchedulableRunnable) iterator.next();
if (next.getNextRun() <= current)
{
iterator.remove();
threadPool.run(next);
}
else
break;
}
}
/**
* Wait for the next outstanding runnable
*/
private synchronized void waitOutstanding()
throws InterruptedException
{
// There is nothing to run
if (runnables.size() == 0)
wait();
else
{
// Wait until the next runnable
SchedulableRunnable next = (SchedulableRunnable) runnables.first();
long wait = next.getNextRun() - System.currentTimeMillis();
if (wait > 0)
wait(wait);
}
}
// Inner Classes -------------------------------------------------
}
1.1 jmx/src/main/org/jboss/mx/util/SchedulableRunnable.java
Index: SchedulableRunnable.java
===================================================================
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.mx.util;
/**
* A schedulable runnable.<p>
*
* Subclasses should implement doRun() to do some real work.<p>
*
* setScheduler(RunnableScheduler) has to be invoked with a RunnableScheduler
* that has been started for the work to be performed. If the doRun() does
* not invoke setNextRun(), the link to the scheduler is removed.
*
* @see RunnableScheduler
*
* @author <a href="mailto:[EMAIL PROTECTED]">Adrian Brock</a>.
* @version $Revision: 1.1 $
*/
public abstract class SchedulableRunnable
implements Comparable, Runnable
{
// Attributes ----------------------------------------------------
/**
* A unique identifier
*/
private long id;
/**
* The next run timestamp
*/
private long nextRun;
/**
* The current scheduler
*/
private RunnableScheduler scheduler;
/**
* Whether we are running
*/
private boolean running;
/**
* Whether we should reschedule after the run
*/
private boolean reschedule;
// Static --------------------------------------------------------
/**
* The next unique identifier
*/
private static long nextId = 0;
// Constructors --------------------------------------------------
/**
* Constructs a new schedulable runnable.
*/
public SchedulableRunnable()
{
this.id = getNextId();
}
// Public --------------------------------------------------------
/**
* Gets the next run timestamp
*
* @return the next run
*/
public long getNextRun()
{
return nextRun;
}
/**
* Sets the next run date<p>
*
* If it is linked to a scheduler, it is temporarily removed while the date
* is modified.
*
* @param nextRun the next run date
*/
public synchronized void setNextRun(long nextRun)
{
// Remove from scheduler
if (scheduler != null)
scheduler.remove(this);
// Set the new run time
this.nextRun = nextRun;
// If we are not running, add it to the scheduler otherwise
// remember we want adding back
if (running == false)
scheduler.add(this);
else
reschedule = true;
}
/**
* Set the scheduler for this runnable
*
* @param the scheduler pass null to remove the runnable from
* any scheduler
* @return the previous scheduler or null if there was no previous
* scheduler
*/
public synchronized RunnableScheduler setScheduler(RunnableScheduler scheduler)
{
// Null operation
if (this.scheduler == scheduler)
return this.scheduler;
// Remember the result
RunnableScheduler result = this.scheduler;
// Remove from previous scheduler
if (this.scheduler != null)
this.scheduler.remove(this);
// Set the new state
this.scheduler = scheduler;
// This is a remove operation
if (scheduler == null)
reschedule = false;
// If we are not running, add it to the scheduler otherwise
// remember we want adding
else if (running == false)
scheduler.add(this);
else
reschedule = true;
// We are done
return result;
}
/**
* Do the work, the scheduled runnable should do its work here
*/
public abstract void doRun();
// Runnable Implementation ---------------------------------------
/**
* Runs doRun()<p>
*
* If setNextRun() is not invoked during the doRun(), the link to the
* scheduler is removed
*/
public final void run()
{
startRun();
try
{
doRun();
}
finally
{
endRun();
}
}
// Runnable Implementation ---------------------------------------
public int compareTo(Object o)
{
SchedulableRunnable other = (SchedulableRunnable) o;
long temp = other.nextRun - this.nextRun;
if (temp < 0)
return -1;
if (temp > 0)
return +1;
temp = other.id - this.id;
if (temp < 0)
return -1;
if (temp > 0)
return +1;
return 0;
}
// Object Overrides ----------------------------------------------
public boolean equals(Object obj)
{
return (compareTo(obj) == 0);
}
// Protected -----------------------------------------------------
// Package -------------------------------------------------------
// Private -------------------------------------------------------
/**
* Start the run
*/
private synchronized void startRun()
{
running = true;
}
/**
* Check whether the work got rescheduled
*/
private synchronized void endRun()
{
running = false;
if (reschedule == true)
scheduler.add(this);
reschedule = false;
}
/**
* Get the next identifier
*/
private static synchronized long getNextId()
{
return nextId++;
}
// Inner Classes -------------------------------------------------
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development