asmuts 02/01/14 22:48:21
Added: src/java/org/apache/stratum/jcs/utils/reuse
HashMapPoolManager.java HashtablePoolManager.java
ICleanForPool.java IJglQueue.java
IKnowCreateTime.java IThreadPoolRunnable.java
ITomcatQueue.java IZombie.java JglQueue.java
ObjectPreserver.java ReadWriteLock.java
ReadWriteLockManager.java RwLockGC.java
RwLockHolder.java ThreadPoolManager.java
TomcatJglQueue.java TomcatQueue.java
Log:
pooling . . . .
Revision Changes Path
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/HashMapPoolManager.java
Index: HashMapPoolManager.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
import org.apache.stratum.jcs.utils.log.*;
/**
* Very simple utility class to be sued by proxy servlets that pass values by means
* of Hastables. Not a singleton manager and not set up to decrement.
* Only get's us about a 15% boost for this line.
*/
public class HashMapPoolManager {
Logger log;
HashMap[] pool;
boolean[] inUse;
///////////////////////////////////////////////////////
public static void main( String args[] ) {
HashMapPoolManager hpm = new HashMapPoolManager( 200 );
int num = 1000000;
long start = System.currentTimeMillis();
for ( int i = 0; i < num; i++ ) {
HashMap ht = new HashMap();
}
long end = System.currentTimeMillis();
System.out.println( "New HashMap creation took " + String.valueOf( end - start )
+ " millis." );
start = System.currentTimeMillis();
for ( int i = 0; i < num; i++ ) {
HashMap ht = hpm.getHashMap();
//ht.put( "tre", "ret" );
hpm.returnHashMap( ht );
}
end = System.currentTimeMillis();
System.out.println( "Pooled get and return of Hashtable took " + String.valueOf(
end - start ) + " millis." );
}
////////////////////////////////////////////////////////////
public HashMapPoolManager(int initialPoolSize) {
log = LoggerManager.getLogger( this );
log.info( "initialPoolSize = " + initialPoolSize );
pool = new HashMap[initialPoolSize];
inUse = new boolean[initialPoolSize];
for (int i = pool.length-1; i>=0; i--) {
pool[i] = new HashMap();
inUse[i] = false;
}
}
////////////////////////////////////////////////////////////
public synchronized HashMap getHashMap() {
for (int i = inUse.length-1; i >= 0; i--)
if (!inUse[i]) {
inUse[i] = true;
return pool[i];
}
//If we got here, then all the HashMaps are in use. We will increase the number
in our
//pool by 10.
boolean[] old_inUse = inUse;
inUse = new boolean[old_inUse.length+10];
System.arraycopy(old_inUse, 0, inUse, 0, old_inUse.length);
HashMap[] old_pool = pool;
pool = new HashMap[old_pool.length+10];
System.arraycopy(old_pool, 0, pool, 0, old_pool.length);
for (int i = old_pool.length; i < pool.length; i++) {
pool[i] = new HashMap();
inUse[i] = false;
}
inUse[pool.length-1] = true;
return pool[pool.length-1];
}
////////////////////////////////////////////////////////////
public synchronized void returnHashMap(HashMap v) {
for (int i = inUse.length-1; i >= 0; i--) {
if (pool[i] == v) {
inUse[i] = false;
v.clear();
return;
}
}
log.warn( "Hashtable was not obtained from the pool: " + v );
}
} // end class
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/HashtablePoolManager.java
Index: HashtablePoolManager.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
import org.apache.stratum.jcs.utils.log.*;
/**
* Very simple utility class to be sued by proxy servlets that pass values by means
* of Hastables. Not a singleton manager and not set up to decrement.
* Only get's us about a 15% boost for this line.
*/
public class HashtablePoolManager {
Logger log;
Hashtable[] pool;
boolean[] inUse;
///////////////////////////////////////////////////////
public static void main( String args[] ) {
HashtablePoolManager hpm = new HashtablePoolManager( 200 );
int num = 1000000;
long start = System.currentTimeMillis();
for ( int i = 0; i < num; i++ ) {
Hashtable ht = new Hashtable();
//ht.put( "tre", "ret" );
}
long end = System.currentTimeMillis();
System.out.println( "New Hashtable creation took " + String.valueOf( end - start
) + " millis." );
start = System.currentTimeMillis();
for ( int i = 0; i < num; i++ ) {
Hashtable ht = hpm.getHashtable();
//ht.put( "tre", "ret" );
hpm.returnHashtable( ht );
}
end = System.currentTimeMillis();
System.out.println( "Pooled get and return of Hashtable took " + String.valueOf(
end - start ) + " millis." );
}
////////////////////////////////////////////////////////////
public HashtablePoolManager(int initialPoolSize) {
LoggerManager lm = LoggerManager.getInstance();
log = lm.getLogger( this );
log.info( "initialPoolSize = " + initialPoolSize );
pool = new Hashtable[initialPoolSize];
inUse = new boolean[initialPoolSize];
for (int i = pool.length-1; i>=0; i--) {
pool[i] = new Hashtable();
inUse[i] = false;
}
}
////////////////////////////////////////////////////////////
public synchronized Hashtable getHashtable() {
for (int i = inUse.length-1; i >= 0; i--)
if (!inUse[i]) {
inUse[i] = true;
return pool[i];
}
//If we got here, then all the Hashtable are in use. We will increase the number
in our
//pool by 10.
boolean[] old_inUse = inUse;
inUse = new boolean[old_inUse.length+10];
System.arraycopy(old_inUse, 0, inUse, 0, old_inUse.length);
Hashtable[] old_pool = pool;
pool = new Hashtable[old_pool.length+10];
System.arraycopy(old_pool, 0, pool, 0, old_pool.length);
for (int i = old_pool.length; i < pool.length; i++) {
pool[i] = new Hashtable();
inUse[i] = false;
}
inUse[pool.length-1] = true;
return pool[pool.length-1];
}
////////////////////////////////////////////////////////////
public synchronized void returnHashtable(Hashtable v) {
for (int i = inUse.length-1; i >= 0; i--) {
if (pool[i] == v) {
inUse[i] = false;
v.clear();
return;
}
}
log.warn( "Hashtable was not obtained from the pool: " + v );
}
} // end class
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ICleanForPool.java
Index: ICleanForPool.java
===================================================================
/*
* put your module comment here
* formatted with JxBeauty (c) [EMAIL PROTECTED]
*/
package org.apache.stratum.jcs.utils.reuse;
import java.io.*;
import java.util.*;
////////////////////////////////////
public interface ICleanForPool {
/**
* Resets default values for reinsertion into a pool.
*/
public void clean ();
} // end interface
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/IJglQueue.java
Index: IJglQueue.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
/** Used to define the interface of a queue from the jgl library. */
public interface IJglQueue {
/**
* Remove all of my objects.
*/
public void clear();
/**
* Return true if I contain no objects.
*/
public boolean isEmpty();
/**
* Return the number of objects that I contain.
*/
public int size();
/**
* Return the maximum number of objects that I can contain.
*/
public int maxSize();
/**
* Return the object at my front.
* @exception com.objectspace.jgl.InvalidOperationException If the Queue is empty.
*/
public Object front();
/**
* Return the object at my back.
* @exception com.objectspace.jgl.InvalidOperationException If the Queue is empty.
*/
public Object back();
/**
* Add an object to my back.
* @param object The object to add.
*/
public Object add (Object object);
/**
* Add an object to my back.
*/
public void push (Object object);
/**
* Remove an object from my front and return it.
* @exception com.objectspace.jgl.InvalidOperationException If the Queue is empty.
*/
public Object pop();
/**
* Return an Enumeration of my components.
*/
public Enumeration elements();
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/IKnowCreateTime.java
Index: IKnowCreateTime.java
===================================================================
/*
* put your module comment here
* formatted with JxBeauty (c) [EMAIL PROTECTED]
*/
package org.apache.stratum.jcs.utils.reuse;
public interface IKnowCreateTime {
public long getCreateTime ();
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/IThreadPoolRunnable.java
Index: IThreadPoolRunnable.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import org.apache.tomcat.util.*;
/**
* Implemented if you want to run a piece of code inside a thread pool.
*/
public interface IThreadPoolRunnable extends ThreadPoolRunnable {
// Super-interface methods duplicated here for easy reference.
/**
* Called when this object is first loaded in the thread pool.
* Important: all workers in a pool must be of the same type,
* otherwise the mechanism becomes more complex.
*/
// public Object[] getInitData();
/**
* This method will be executed in one of the pool's threads. The
* thread will be returned to the pool.
*/
// public void runIt(Object thData[]);
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ITomcatQueue.java
Index: ITomcatQueue.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
/** Used to define the interface of a queue from Jakarta Tomcat library. */
public interface ITomcatQueue {
/**
* Put the object into the queue.
*
* @param object the object to be appended to the
* queue.
*/
public void put(Object object);
/**
* Pull the first object out of the queue. Wait if the queue is
* empty.
*/
public Object pull();
/**
* Get the first object out of the queue. Return null if the queue
* is empty.
*/
public Object get();
/**
* Peek to see if something is available.
*/
public Object peek();
/**
* Is the queue empty?
*/
public boolean isEmpty();
/**
* How many elements are there in this queue?
*/
public int size();
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/IZombie.java
Index: IZombie.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
/** Interface to mark an object as zombie for error recovery purposes. */
public interface IZombie {
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/JglQueue.java
Index: JglQueue.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import com.objectspace.jgl.*;
public class JglQueue extends Queue implements IJglQueue {
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ObjectPreserver.java
Index: ObjectPreserver.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
/**
* This class can help ensure that an object is never garbage
* collected.
*/
public class ObjectPreserver implements Runnable {
// This keeps this class and everything it references from being
// garbage collected
private static ObjectPreserver lifeLine = new ObjectPreserver();
// Since this class won't be garbage collected, neither will this
// HashSet or the object that it references.
private static HashSet protectedSet = new HashSet();
/**
* Constructor.
*/
private ObjectPreserver() {
new Thread(this).start();
} // constructor()
public void run() {
while (true) {
try {
synchronized(this) {
wait();
}
} catch (InterruptedException e) {
}
}
}
/**
* Garbage collection of objects passed to this method will be
* prevented until they are passed to the unpreserveObject method.
*/
public static void preserveObject(Object o) {
protectedSet.add(o);
} // preserveObject()
/**
* Objects passed to this method lose the protection that the
* preserveObject method gave them from garbage collection.
*/
public static void unpreserveObject(Object o) {
protectedSet.remove(o);
} // unpreserveObject(Object)
} // class ObjectPreserver
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ReadWriteLock.java
Index: ReadWriteLock.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
/**
* This class coordinates concurrent calls to an object's get and set methods so
that calls to the
* object set methods do not interfere with each other or with calls to the object's
get methods.
*<br><br>
* Only a single instance of this class should be created per specific resource
* that requires Read/Write lock protection.
* <br><br>
* The invariant required by this class is that the method <code>done</code> must be
called,
* and only be called, after a previous call to either the method
* <code>readLock</code> or <code>writeLock</code>.
*/
class ReadWriteLock {
//////////////// debug MUST BE SET TO false in production! ///////////////////
private boolean debug = false; //true;
/** Number of threads waiting to read. */
private int waitingForReadLock = 0;
/** Number of threads reading. */
private int outstandingReadLocks = 0;
/** The thread that has the write lock or null. */
private Thread writeLockedThread;
/** The number of (nested) write locks that have been requested from
writeLockedThread. */
private int outstandingWriteLocks = 0;
/**
* Threads waiting to get a write lock are tracked in this ArrayList
* to ensure that write locks are issued in the same order they are
* requested.
*/
private ArrayList waitingForWriteLock = new ArrayList();
/** Default constructor. */
ReadWriteLock () {
}
/**
* Issue a read lock if there is no outstanding write lock or
* threads waiting to get a write lock.
* Caller of this method must be careful to avoid synchronizing the calling code
so as to avoid deadlock.
*/
synchronized void readLock () throws InterruptedException {
waitingForReadLock++;
while (writeLockedThread != null) {
p("readLock wait");
wait();
p("wake up from readLock wait");
}
if (debug)
p("readLock acquired");
waitingForReadLock--;
outstandingReadLocks++;
}
/**
* Issue a write lock if there are no outstanding read or write locks.
* Caller of this method must be careful to avoid synchronizing the calling code
so as to avoid deadlock.
*/
void writeLock () throws InterruptedException {
Thread thisThread = Thread.currentThread();
synchronized (this) {
if (writeLockedThread == null && outstandingReadLocks == 0) {
writeLockedThread = Thread.currentThread();
outstandingWriteLocks++;
if (debug)
p("writeLock acquired without waiting");
return;
}
if (writeLockedThread == thisThread) // nested write locks from the same
thread.
outstandingWriteLocks++;
waitingForWriteLock.add(thisThread);
}
synchronized (thisThread) {
while (thisThread != writeLockedThread) {
p("writeLock wait");
// set this so if there is an error the app will not completely die!
thisThread.wait(2000);
p("wake up from writeLock wait");
}
if (debug)
p("writeLock acquired");
}
synchronized (this) {
int i = waitingForWriteLock.indexOf(thisThread);
waitingForWriteLock.remove(i);
}
}
/**
* Threads call this method to relinquish a lock that they
* previously got from this object.
* @throws IllegalStateException if called when there are no
* outstanding locks or there is a write lock issued to a
* different thread.
*/
synchronized void done () {
if (outstandingReadLocks > 0) {
outstandingReadLocks--;
if (outstandingReadLocks == 0 && waitingForWriteLock.size() > 0) {
writeLockedThread = (Thread)waitingForWriteLock.get(0);
if (debug)
p("readLock released and before notifying a write lock waiting thread "
+ writeLockedThread);
synchronized (writeLockedThread) {
writeLockedThread.notifyAll();
}
if (debug)
p("readLock released and after notifying a write lock waiting thread "
+ writeLockedThread);
}
else if (debug)
p("readLock released without fuss");
return;
}
if (Thread.currentThread() == writeLockedThread) {
outstandingWriteLocks--;
if (outstandingWriteLocks > 0) {
p("writeLock released for a nested writeLock request.");
return;
}
if (outstandingReadLocks == 0 && waitingForWriteLock.size() > 0) {
writeLockedThread = (Thread)waitingForWriteLock.get(0);
if (debug)
p("writeLock released and before notifying a write lock waiting thread "
+ writeLockedThread);
synchronized (writeLockedThread) {
writeLockedThread.notifyAll();
}
if (debug)
p("writeLock released and after notifying a write lock waiting thread "
+ writeLockedThread);
}
else {
writeLockedThread = null;
if (waitingForReadLock > 0) {
if (debug)
p("writeLock released and notify all read lock waiting threads.");
notifyAll();
}
else if (debug)
p("writeLock released without fuss.");
}
return;
}
//////////////// debug MUST BE SET TO false in production! ///////////////////
if (debug) {
try {
System.in.read();
} catch (java.io.IOException ignore) {}
}
throw new IllegalStateException("Thread does not have lock");
}
private void p (String s) {
if (debug)
System.out.println("ReadWriteLock: " + Thread.currentThread() + ">>" +
s);
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ReadWriteLockManager.java
Index: ReadWriteLockManager.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
/** The Generic ReadWriteLock Manager for various resources. */
public abstract class ReadWriteLockManager {
public static final boolean debug = false;
/** Used to asynchronously remove unused RwLockHolder objects managed ty this
manager. */
private static RwLockGC gc;
/** Class name for debugging purposes. */
private String clsname;
/** Places a read lock on the specified resource. */
final public void readLock (String id) throws InterruptedException {
lock(id, false);
}
/** Places a write lock on the specified resource. */
final public void writeLock (String id) throws InterruptedException {
lock(id, true);
}
/** Release the read/write lock previously placed on the specified resource. */
final public void done (String id) {
Hashtable ht = getLocks();
RwLockHolder holder = (RwLockHolder)ht.get(id);
if (holder == null) {
p("Method done of " + getClass().getName() + " invoked without an outstanding
lock; id=" + id);
//System.exit(1);
throw new IllegalStateException("Method done of " + getClass().getName()
+ " invoked without an outstanding lock; id=" + id);
}
holder.rwlock.done();
if ( debug ) {
p("lock done for id = " + id );
}
// Somehow if we don't synchronize while changing the count,
// the count went down below zero!
// Theoretically this should never happen, as a "done" is always preceeded
// by either a read or write lock issued from the very same thread.
// So for the moment, let's blame the JVM and make it work via synchronization,
// until futher investigation.
int lcount; // used to minimize the time spent in the synchronized block.
synchronized(ht) {
lcount = --holder.lcount;
}
if (lcount > 0) {
return;
}
// p("-- holder.lcount=" + holder.lcount);
if (lcount == 0) {
holder.lastInactiveTime = System.currentTimeMillis();
//p("notify: Gargage available");
gc.notifyGarbage();
return;
}
// lcount is negative! should never get here.
/*
p("holder.lcount went down below zero (" + holder.lcount + ") for id=" + id);
System.exit(1);
*/
throw new IllegalStateException("holder.lcount went down below zero ("
+ holder.lcount + ") for id=" + id);
}
/** Places either a read or write lock on the specified resource. */
private void lock (String id, boolean isWrite) throws InterruptedException {
if ( debug ) {
p("about to get lock, isWrite=" + isWrite + " for id = " + id);
}
RwLockHolder holder;
Hashtable ht = getLocks();
if (gc == null) {
synchronized (this) {
if (gc == null) {
gc = new RwLockGC(ht);
gc.setDaemon(true);
gc.start();
}
}
}
synchronized(ht) {
holder = (RwLockHolder)ht.get(id);
if (holder != null) {
// Lock already exists. So just use it.
holder.lcount++;
if ( debug ) {
p("++ holder.lcount=" + holder.lcount + ", isWrite=" + isWrite + " for id
= " + id);
}
}
}
if (holder == null) {
// Lock does not exist. So create a new one.
RwLockHolder newHolder = new RwLockHolder(new ReadWriteLock());
if ( debug ) {
p("holder is null, isWrite=" + isWrite);
}
synchronized(ht) {
holder = (RwLockHolder)ht.put(id, newHolder);
if (holder != null) {
// Oops, the lock is already created by someone else concurrently.
// So we increment, put it back and discard the new lock we just created.
// We use this strategy to minimize the time spent in the synchronized
block.
holder.lcount++;
ht.put(id, holder);
}
}
if (holder == null) {
// no concurrency issue -- the new lock is now used.
holder = newHolder;
}
if (debug) {
p((isWrite ? "Write" : "Read") + " lock created for " + id);
}
}
// Be careful not to put the following code into a synchronized block.
// Otherwise, deadlock can easily happen as the writeLock() and readLock() may
result
// in the ReadWriteLock object being waited!
if (isWrite) {
holder.rwlock.writeLock();
} else {
holder.rwlock.readLock();
}
return;
}
/** Returns the lock table of all the resources managed by the subclass. */
abstract protected Hashtable getLocks ();
/** Subclass must always override this constructor to create and preserve a
singleton instance of the subclass. */
protected ReadWriteLockManager () {
clsname = getClass().getName();
clsname = clsname.substring(clsname.lastIndexOf('.') + 1);
}
private void p (String s) {
// System.err.println(clsname + "#" + Thread.currentThread() + ">>" + s);
System.err.println(">> " + s);
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/RwLockGC.java
Index: RwLockGC.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import org.apache.stratum.jcs.utils.log.*;
import java.util.*;
/**
* Used to enhance performance by delaying the removal of unreferenced RwLockHolder
objects
* managed by the ReadWriteLockManager.
*/
public class RwLockGC extends Thread {
private final Hashtable ht;
private static final long IDLE_PERIOD = 60*1000; // 60 seconds.
private Logger log = LoggerManager.getInstance().getLogger(this);
private boolean clean = true;
RwLockGC (Hashtable ht) {
this.ht = ht;
}
/**
* Notifies the garbage collection that there is garbage available,
* and kicks off the garbage collection process.
*/
void notifyGarbage () {
dirty();
synchronized (this) {
notify();
}
}
// Run forever.
// Minimize the use of any synchronization in the process of garbage collection
// for performance reason.
public void run () {
do {
if (clean) {
synchronized (this) {
if (clean) {
//p("RwLockGC entering into a wait state");
// Garbage driven mode.
try {
wait(); // wake up only if there is garbage.
} catch (InterruptedException ignore) {}
}
}
}
// Time driven mode: sleep between each round of garbage collection.
try {
//p("RwLockGC sleeping for " + IDLE_PERIOD);
Thread.currentThread().sleep(IDLE_PERIOD);
} catch (InterruptedException ex) {
// ignore;
}
// The "clean" flag must be false here.
// Simply presume we can collect all the garbage until proven otherwise.
synchronized (this) {
clean = true;
}
long now = System.currentTimeMillis();
// Take a snapshot of the hashtable.
Map.Entry[] entries = (Map.Entry[])ht.entrySet().toArray(new Map.Entry[0]);
//p("RwLockHolder garbage collecting...");
for (int i = 0; i < entries.length; i++) {
RwLockHolder holder = (RwLockHolder)entries[i].getValue();
if (holder.removable(now)) {
Object key = entries[i].getKey();
synchronized (ht) {
holder = (RwLockHolder)ht.get(key);
// holder cannot possibly be null as this should be the only thread
removing them.
if (holder.removable(now)) {
ht.remove(key);
/*
p("removing key=" + key + ", now=" + now + ", holder.lastInactiveTime="
+ holder.lastInactiveTime);
*/
}
}
}
} // end for loop.
} while (true);
}
/** Sets the "clean" flag to false in a critial section. */
private void dirty () {
if (clean) {
synchronized (this) {
clean = false;
}
}
}
private void p (String s) {
System.out.println("RwLockGC:" + s);
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/RwLockHolder.java
Index: RwLockHolder.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
/**
* Used to keep track of the total number of outstanding locks placed
* but not yet released for a given resource.
*/
class RwLockHolder {
private static final long UNUSED_TIME = 10*1000; // 10 seconds.
/** Read/Write lock for a specific resource. */
final ReadWriteLock rwlock;
/** Number of locks that have been placed on the rwlock and not yet released. */
int lcount = 1;
/** Last timestamp when the lcount was zero. */
long lastInactiveTime = -1;
/** Constructs with a Read/Write lock for a specific resource. */
RwLockHolder (ReadWriteLock rwlock) {
this.rwlock = rwlock;
}
/**
* Returns true iff this object satisfies the condition of removing RwLockHolder
* from the managing ReadWriteLockManager.
*/
boolean removable (long now) {
return lcount == 0 && lastInactiveTime > 0 && now - lastInactiveTime >
UNUSED_TIME;
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/ThreadPoolManager.java
Index: ThreadPoolManager.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import java.util.*;
import org.apache.tomcat.util.*;
/** Provides a singleton thread pool. */
public class ThreadPoolManager {
/** The singleton thread pool manager. */
private static final ThreadPoolManager singleton = new ThreadPoolManager();
/** The thread pool. */
private ThreadPool pool = new ThreadPool();
/** True iff the thread pool has been started. */
private boolean started;
/** Can only be constructed by this class. */
private ThreadPoolManager() {}
/**
* Sets the max number of threads that you can open in the pool.
* Will only be effective if called before the getInstance method is invoked for
the first time.
*/
public static void setMaxThreads(int maxThreads) {
singleton.pool.setMaxThreads(maxThreads);
}
/**
* Sets the min number of idle threads that you can leave in the pool.
* Will only be effective if called before the getInstance method is invoked for
the first time.
*/
public static void setMinSpareThreads(int minSpareThreads) {
singleton.pool.setMinSpareThreads(minSpareThreads);
}
/**
* Sets the max number of idle threads that you can leave in the pool.
* Will only be effective if called before the getInstance method is invoked for
the first time.
*/
public static void setMaxSpareThreads(int maxSpareThreads) {
singleton.pool.setMaxSpareThreads(maxSpareThreads);
}
/**
* Gets the max number of threads that you can open in the pool.
* Will only be accurate if called after the getInstance method is invoked for the
first time.
*/
public static int getMaxThreads() {
return singleton.pool.getMaxThreads();
}
/**
* Gets the min number of idle threads that you can leave in the pool.
* Will only be accurate if called after the getInstance method is invoked for the
first time.
*/
public static int getMinSpareThreads() {
return singleton.pool.getMinSpareThreads();
}
/**
* Gets the max number of idle threads that you can leave in the pool.
* Will only be accurate if called after the getInstance method is invoked for the
first time.
*/
public static int getMaxSpareThreads() {
return singleton.pool.getMaxSpareThreads();
}
/**
* Returns the singleton thread pool manager, which can be used to execute a
* given IThreadPoolRunnable on a thread in the pool.
* Configuration of the thread pool must be made prior to invoking this method.
*/
public static ThreadPoolManager getInstance() {
if (!singleton.started) {
synchronized(singleton) {
if (!singleton.started) {
singleton.pool.start();
singleton.started = true;
}
}
}
return singleton;
}
/**
* Shuts down the thread pool and re-initializes it to the default.
*/
public static void reset() {
synchronized(singleton) {
if (singleton.started) {
singleton.started = false;
singleton.pool.shutdown();
}
singleton.pool = new ThreadPool();
}
return;
}
/**
* Executes a given IThreadPoolRunnable on a thread in the pool, block if needed.
*/
public void runIt(IThreadPoolRunnable r) {
pool.runIt(r);
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/TomcatJglQueue.java
Index: TomcatJglQueue.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
/**
* A simple FIFO queue class which causes the calling thread to wait
* if the queue is empty and notifies threads that are waiting when it
* is not empty. Implemented using JGL for better performance.
*/
public class TomcatJglQueue implements ITomcatQueue {
private IJglQueue q = new JglQueue();
/**
* Put the object into the queue.
*
* @param object the object to be appended to the
* queue.
*/
public void put(Object object) {
synchronized(q) {
q.push(object);
q.notify();
}
}
/**
* Pull the first object out of the queue. Wait if the queue is
* empty.
*/
public Object pull() {
synchronized(q) {
while (q.isEmpty()) {
try {
q.wait();
} catch(InterruptedException ex) {}
}
return q.pop();
}
}
/**
* Get the first object out of the queue. Return null if the queue
* is empty.
*/
public Object get() {
synchronized(q) {
return q.isEmpty() ? null : q.pop();
}
}
/**
* Peek to see if something is available.
*/
public Object peek() {
synchronized(q) {
return q.isEmpty() ? null : q.front();
}
}
/**
* Is the queue empty?
*/
public boolean isEmpty() {
return q.isEmpty();
}
/**
* How many elements are there in this queue?
*/
public int size() {
return q.size();
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/reuse/TomcatQueue.java
Index: TomcatQueue.java
===================================================================
package org.apache.stratum.jcs.utils.reuse;
import org.apache.tomcat.util.*;
/**
* A simple FIFO queue class which causes the calling thread to wait
* if the queue is empty and notifies threads that are waiting when it
* is not empty. Implemented using the Tomcat Queue.
*/
public class TomcatQueue extends Queue implements ITomcatQueue {
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>