This document describes why this is useful to do and how this could be achieved.
<!ELEMENT thread-pool-config (thread-pool+)>
<!--
thread-pool-id
This is an id for the work-queue e.g. "thread-pool-1", "thread-pool-2"
etc
min-thread-pool-size
Minimum number of threads in the threadpool servicing requests in this
queue.
These are created up front when this threadpool is instantiated
max-thread-pool-size
Maximum number of threads in the threadpool servicing requests in this
queue
This is the upper bound on the no. of threads that exist in the
threadpool.
idle-thread-timeout-in-seconds idle threads are
removed from pool, after this time
num-work-queues
This denotes the total number of work queues that are serviced by this
threadpool.
Default value would be 1
-->
<!ELEMENT thread-pool(EMPTY)>
<!ATTLIST thread-pool
thread-pool-id
CDATA #REQUIRED
min-thread-pool-size
CDATA "0"
max-thread-pool-size
CDATA "200"
idle-thread-timeout-in-seconds CDATA "120"
num-work-queues
CDATA "1">
<!-- The ORB element would look like ...
use-thread-pool-ids
This would refer to the thread-pool-id(s) defined in the thread-pool
sub-element of
thread-pool-config element in server.xml. These would be the threadpool(s) used
by the
ORB. More than one thread-pool-id(s) could be specified by using commas to
separate
the names e.g. "orb-thread-pool-1, orb-thread-pool-2"
-->
<!ELEMENT orb (property*)>
<!ATTLIST orb
message-fragment-size
CDATA "1024"
use-thread-pool-ids
IDREFS #REQUIRED
max-connections
CDATA "1024"
....
...>
Essentially, thread-pool-config is a server wide element, that consists of atleast 1 or more thread-pool elements.
A ThreadPoolManagerImpl class could be used as a singleton instance, to create all the ThreadPools at server startup using the configuration parameters defined in the threadpool-config element of the server.xml. Any component can then get the threadpool instance by providing the threadpool-id to this singleton ThreadPoolManager instance. Using this threadpool instance a work queue serviced by this threadpool can be obtained. Work can be added to the queue and it will get processed by the threads of the threadpool.
EJB descriptors (or module descriptors - not sure if there is anything
like this) could use the threadpool-ids defined in the server.xml to denote if
the EJB (module) would want to use a dedicated threadpool. This could be done
to avoid starvation. If nothing is specified or incorrect threadpool-id is
specified in the bean descriptors, then the threadpool associated with the ORB
will be used to service requests from that bean.
This interface will be implemented by the ThreadPoolManagerImpl class in
App. Server PE 8.0. It will be responsible for returning an instance of the
ThreadPool given a thread-pool-id, from any component that wants to use a
ThreadPool. In addition, ThreadPoolManagerImpl class will be responsible for
creating all the threadpools (and their queues) at server startup time. This is
done using the config bean that reads the thread-pool-config element in
server.xml. ThreadPoolManager instance would be a singleton instance in the
App. Server process.
public interface ThreadPoolManager {
/**
* This method will return an instance of the threadpool given a
threadpoolId,
* that
can be used by any component in the app. server.
*/
public ThreadPool getThreadPool(String
threadpoolId);
/**
* This method will return an instance of the threadpool given a numeric
threadpoolId.
* This
method will be used by the ORB to support the functionality of
* dedicated threadpool for EJB
beans
*/
public ThreadPool
getThreadPool(int numericIdForThreadpool);
/**
* This method is used to return the numeric id of the threadpool, given a
String
*
threadpoolId. This is used by the POA interceptors to add the numeric
threadpool
* Id, as
a tagged component in the IOR. This is used to provide the functionality
of
* dedicated
threadpool for EJB beans
*/
public int getNumericId(String
threadpoolId);
/**
* Return a String Id for a numericId of a threadpool managed by the
threadpool
*
manager
*/
public String
getStringId(int numericIdForThreadpool);
/**
* Returns the first instance of ThreadPool in the ThreadPoolManager
*/
public ThreadPool
getDefaultThreadPool();
}
An implementation of this SPI will also exist in the ORB that ships with
J2SE, so that the ORB code that uses these API does not change for J2SE.
The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport. I am adding more APIs to the designed interface for this done by Harold Carr.
public interface ThreadPool {
/**
* This method will return any instance of the WorkQueue. If the
ThreadPool
*
instance only services one WorkQueue then that WorkQueue instance
will
* be returned.
If there are more than one WorkQueues serviced by this
* ThreadPool, then this method would return
a WorkQueue based on the
* implementation of the class that
implements this interface. For PE 8.0 we
* would return a WorkQueue in a roundrobin
fashion everytime this method
* is called. In the future we could allow
pluggability of Policy objects for this.
*/
public WorkQueue
getAnyWorkQueue();
/**
* This method will return an instance of the of the WorkQueue given a
queueId.
* This will
be useful in situations where there are more than one WorkQueues
* managed by the ThreadPool and
the user of the ThreadPool wants to always use
* the same WorkQueue for doing the
Work.
* If the
number of WorkQueues in the ThreadPool are 10, then queueIds will go
* from 0-9
*/
public WorkQueue getWorkQueue(int
queueId);
/**
* This method will return the number of WorkQueues serviced by the
threadpool.
*/
public int
numberOfWorkQueues();
/**
* This method will return the minimum number of threads maintained by the
threadpool.
*/
public int
minimumNumberOfThreads();
/**
* This method will return the maximum number of threads in the threadpool at
any
* point in time,
for the life of the threadpool
*/
public int
maximumNumberOfThreads();
/**
* This method will return the time in milliseconds when idle threads in the
threadpool are
*
removed.
*/
public long
idleTimeoutForThreads();
/**
* This method will return the current number of threads in the threadpool. This
method
* returns a
value which is not synchronized.
*/
public int
currentNumberOfThreads();
/**
* This method will return the number of available threads in the threadpool
which are
*
waiting for work. This method returns a value which is not
synchronized.
*/
public int
numberOfAvailableThreads();
/**
* This method will return the number of busy threads in the
threadpool
* This
method returns a value which is not synchronized.
*/
public int
numberOfBusyThreads();
/**
* This method returns the number of Work items processed by the
threadpool
*/
public long
currentProcessedCount();
/**
* This method will return the name of the threadpool.
*/
public String getName();
}
The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport by Harold Carr. The following has been borrowed from that design
public interface WorkQueue {
/**
* This method is used to add work to the WorkQueue
*/
public void addWork(Work
aWorkItem);
/**
* This method will return the name of the WorkQueue.
*/
public String getName();
/**
* Returns the total number of Work items added to the Queue.
*/
public long
totalWorkItemsAdded();
/**
* Returns the total number of Work items in the Queue to be
processed.
*/
public int
workItemsInQueue();
}
The ORB already has plans for having an interface like that as part of the work being done on the design of the ORB transport by Harold Carr. The following has been borrowed from that design
public interface Work {
public void doWork();
public String getName();
}