User: starksm Date: 01/11/26 17:16:21 Modified: src/main/org/jboss/ejb/plugins Tag: Branch_2_4 AbstractInstanceCache.java Log: Use a single daemon thread to passivate all EJBs rather than a thread per container as this is wasteful of threads, especially when large numbers of beans are deployed. Revision Changes Path No revision No revision 1.10.2.4 +32 -109 jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java Index: AbstractInstanceCache.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java,v retrieving revision 1.10.2.3 retrieving revision 1.10.2.4 diff -u -r1.10.2.3 -r1.10.2.4 --- AbstractInstanceCache.java 2001/11/20 09:42:49 1.10.2.3 +++ AbstractInstanceCache.java 2001/11/27 01:16:21 1.10.2.4 @@ -62,8 +62,9 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Simone Bordet</a> * @author <a href="[EMAIL PROTECTED]">Bill Burke</a> * @author <a href="[EMAIL PROTECTED]">Marc Fleury</a> + * @author <a href="[EMAIL PROTECTED]">Scott Stark</a> * - * @version $Revision: 1.10.2.3 $ + * @version $Revision: 1.10.2.4 $ * * <p><b>Revisions:</b> * @@ -91,13 +92,22 @@ implements InstanceCache, XmlLoadable, Monitorable, MetricsConstants { // Constants ----------------------------------------------------- - protected Logger log = Logger.getLogger(getClass()); - + /* The worker queue that passivates beans in another thread. One passivator + is shared for all EJB deployments. + */ + static private WorkerQueue m_passivator = new WorkerQueue("EJB Passivator Thread", true); + static + { + // Start the passivator thread + m_passivator.start(); + } + // Attributes ---------------------------------------------------- + /** The log for this cache instance */ + protected Logger log = Logger.getLogger(getClass()); /* The object that is delegated to implement the desired caching policy */ private CachePolicy m_cache; - /* The worker queue that passivates beans in another thread */ - private WorkerQueue m_passivator; + /* The mutex object for the cache */ private Object m_cacheLock = new Object(); /* Helper class that handles synchronization for the passivation thread */ @@ -291,7 +301,7 @@ } } } - + public boolean isActive(Object id) { // Check whether an object with the given id is available in the cache @@ -335,9 +345,6 @@ { getCache().init(); m_passivationHelper = new PassivationHelper(); - String threadName = "Passivator Thread for " + getContainer().getBeanMetaData().getEjbName(); - ClassLoader cl = getContainer().getClassLoader(); - m_passivator = new PassivatorQueue(threadName, cl); if (isJMSMonitoringEnabled()) { @@ -358,8 +365,6 @@ public void start() throws Exception { getCache().start(); - m_passivator.start(); - if (isJMSMonitoringEnabled()) { m_jmsConnection.start(); @@ -373,9 +378,7 @@ { getCache().stop(); } - - if (m_passivator != null) {m_passivator.stop();} - + if (isJMSMonitoringEnabled() && m_jmsConnection != null) { try @@ -621,7 +624,8 @@ // with a valid key because it may get freed to the InstancePool, then // reused before the PassivationJob executes. // marcf, actually for simplicity I have removed the "freed" call in the pool (check entity pool) - PassivationJob job = new PassivationJob(bean, key) + ClassLoader jobCL = bean.getContainer().getClassLoader(); + PassivationJob job = new PassivationJob(bean, key, jobCL) { public void execute() throws Exception { @@ -632,9 +636,7 @@ // but not yet executed, and in the meanwhile the bean has been removed. return; } - Object id = this.getKey(); - /** * Synchronization / Passivation explanations: * The instance interceptor (II) first acquires the Sync object associated @@ -657,13 +659,14 @@ */ BeanLock lock = getContainer().getLockManager().getLock(id); lock.sync(); - try { - + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(this.m_cl); // marcf: the mutex is not good as we need a thread reentrant one, for now we // use straight synchronization on the ctx as there is a one-one relationship // Also the ctx are not reused any longer so no chance of using the wrong ctx // mutex.acquire(); - synchronized (getCacheLock()) { // This is absolutely fundamental: the job must be removed from @@ -722,7 +725,6 @@ passivate(ctx); executed(); freeContext(ctx); - logPassivation(id); } catch (RemoteException x) @@ -739,6 +741,7 @@ }//synchronized(ctx) finally { + Thread.currentThread().setContextClassLoader(cl); lock.releaseSync(); getContainer().getLockManager().removeLockRef(id); } @@ -811,15 +814,17 @@ */ abstract class PassivationJob implements Executable { - private EnterpriseContext m_context; - private Object m_key; - private boolean m_cancelled; - private boolean m_executed; - - PassivationJob(EnterpriseContext ctx, Object key) + protected EnterpriseContext m_context; + protected Object m_key; + protected boolean m_cancelled; + protected boolean m_executed; + protected ClassLoader m_cl; + + PassivationJob(EnterpriseContext ctx, Object key, ClassLoader cl) { m_context = ctx; m_key = key; + m_cl = cl; } public abstract void execute() throws Exception; @@ -874,87 +879,5 @@ final synchronized boolean isExecuted() { return m_executed; - } -} - -class PassivatorQueue extends WorkerQueue -{ - protected Logger log = Logger.getLogger(PassivatorQueue.class); - /** - * Used for debug purposes, holds the scheduled passivation jobs - */ - // private Map m_map = new HashMap(); - - /** - * Creates a new passivator queue with default thread name of - * "Passivator Thread". - */ - PassivatorQueue() - { - this("Passivator Thread", null); - } - /** - * Creates a new passivator queue with the given thread name and given - * context class loader. <br> - * @param threadName the name of the passivator thread - * @param cl the context class loader; if null the context class loader is not set. - */ - PassivatorQueue(String threadName, ClassLoader cl) - { - super(threadName); - if (cl != null) - { - m_queueThread.setContextClassLoader(cl); - } - } - /** - * Overridden for debug purposes - *//* - protected Executable getJobImpl() throws InterruptedException - { - PassivationJob j = (PassivationJob)super.getJobImpl(); - EnterpriseContext ctx = j.getEnterpriseContext(); - Object id = ctx.getId(); - m_map.remove(id); - return j; - } - */ - /** - * Overridden for debug purposes - *//* - protected void putJobImpl(Executable job) - { - PassivationJob j = (PassivationJob)job; - EnterpriseContext ctx = j.getEnterpriseContext(); - Object id = ctx.getId(); - if (m_map.get(id) != null) - { - // Here is a bug, job requests are scheduled only once per bean. - System.err.println("DUPLICATE PASSIVATION JOB INSERTION FOR ID = " + ctx.getId()); - System.err.println("CTX isLocked: " + ctx.isLocked()); - System.err.println("CTX transaction: " + ctx.getTransaction()); - throw new IllegalStateException(); - } - else - { - m_map.put(id, job); - } - super.putJobImpl(job); - } - */ - /** - * Logs exceptions thrown during job execution. - */ - protected void logJobException(Exception x) - { - // Log system exceptions - if (x instanceof EJBException) - { - log.error("BEAN EXCEPTION:", x); - } - else - { - log.error("EXCEPTION", x); - } } }
_______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development