Author: tv
Date: Thu Dec  3 16:41:49 2015
New Revision: 1717801

URL: http://svn.apache.org/viewvc?rev=1717801&view=rev
Log:
Address issues reported by Findbugs

Added:
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
   (with props)
Modified:
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheListeners.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManager.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/JCSConcurrentCacheAccessUnitTest.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/access/TestCacheAccess.java
    
commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/threadpool/ThreadPoolManagerUnitTest.java
    commons/proper/jcs/trunk/src/changes/changes.xml

Added: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java?rev=1717801&view=auto
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
 (added)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
 Thu Dec  3 16:41:49 2015
@@ -0,0 +1,215 @@
+package org.apache.commons.jcs.auxiliary;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Used to monitor and repair any failed connection for the lateral cache 
service. By default the
+ * monitor operates in a failure driven mode. That is, it goes into a wait 
state until there is an
+ * error. Upon the notification of a connection error, the monitor changes to 
operate in a time
+ * driven mode. That is, it attempts to recover the connections on a periodic 
basis. When all failed
+ * connections are restored, it changes back to the failure driven mode.
+ */
+public abstract class AbstractAuxiliaryCacheMonitor extends Thread
+{
+    /** The logger */
+    protected final Log log = LogFactory.getLog( this.getClass() );
+
+    /** How long to wait between runs */
+    protected static long idlePeriod = 20 * 1000;
+
+    /**
+     * Must make sure AbstractAuxiliaryCacheMonitor is started before any 
error can be detected!
+     */
+    private AtomicBoolean allright = new AtomicBoolean(true);
+
+    /**
+     * shutdown flag
+     */
+    private AtomicBoolean shutdown = new AtomicBoolean(false);
+
+    /** Synchronization helper lock */
+    private Lock lock = new ReentrantLock();
+
+    /** Synchronization helper condition */
+    private Condition trigger = lock.newCondition();
+
+    /**
+     * Constructor
+     *
+     * @param name the thread name
+     */
+    public AbstractAuxiliaryCacheMonitor(String name)
+    {
+        super(name);
+    }
+
+    /**
+     * Configures the idle period between repairs.
+     * <p>
+     * @param idlePeriod The new idlePeriod value
+     */
+    public static void setIdlePeriod( long idlePeriod )
+    {
+        if ( idlePeriod > AbstractAuxiliaryCacheMonitor.idlePeriod )
+        {
+            AbstractAuxiliaryCacheMonitor.idlePeriod = idlePeriod;
+        }
+    }
+
+    /**
+     * Set error condition unconditionally
+     */
+    protected void setError(boolean state)
+    {
+        allright.set(!state);
+    }
+
+    /**
+     * Notifies the cache monitor that an error occurred, and kicks off the 
error recovery process.
+     */
+    public void notifyError()
+    {
+        if (allright.compareAndSet(true, false))
+        {
+            signalTrigger();
+        }
+    }
+
+    /**
+     * Notifies the cache monitor that the service shall shut down
+     */
+    public void notifyShutdown()
+    {
+        if (shutdown.compareAndSet(false, true))
+        {
+            signalTrigger();
+        }
+    }
+
+    // Trigger continuation of loop
+    private void signalTrigger()
+    {
+        try
+        {
+            lock.lock();
+            trigger.signal();
+        }
+        finally
+        {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Clean up all resources before shutdown
+     */
+    protected abstract void dispose();
+
+    /**
+     * do actual work
+     */
+    protected abstract void doWork();
+
+
+    /**
+     * Main processing method for the AbstractAuxiliaryCacheMonitor object
+     */
+    @Override
+    public void run()
+    {
+        do
+        {
+            if ( log.isDebugEnabled() )
+            {
+                if ( allright.get() )
+                {
+                    log.debug( "ERROR DRIVEN MODE: allright = true, cache 
monitor will wait for an error." );
+                }
+                else
+                {
+                    log.debug( "ERROR DRIVEN MODE: allright = false cache 
monitor running." );
+                }
+            }
+
+            if ( allright.get() )
+            {
+                // Failure driven mode.
+                try
+                {
+                    lock.lock();
+                    trigger.await();
+                    // wake up only if there is an error.
+                }
+                catch ( InterruptedException ignore )
+                {
+                    //no op, this is expected
+                }
+                finally
+                {
+                    lock.unlock();
+                }
+            }
+
+            // check for requested shutdown
+            if ( shutdown.get() )
+            {
+                log.info( "Shutting down cache monitor" );
+                dispose();
+                return;
+            }
+
+            // The "allright" flag must be false here.
+            // Simply presume we can fix all the errors until proven otherwise.
+            allright.set(true);
+
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "Cache monitor running." );
+            }
+
+            doWork();
+
+            try
+            {
+                // don't want to sleep after waking from an error
+                // run immediately and sleep here.
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( "Cache monitor sleeping for " + idlePeriod + " 
between runs." );
+                }
+
+                Thread.sleep( idlePeriod );
+            }
+            catch ( InterruptedException ex )
+            {
+                // ignore;
+            }
+        }
+        while ( true );
+    }
+}

Propchange: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
 Thu Dec  3 16:41:49 2015
@@ -700,24 +700,26 @@ public class BlockDiskCache<K, V>
         elems.add(new StatElement<Boolean>( "Is Alive", Boolean.valueOf(alive) 
) );
         elems.add(new StatElement<Integer>( "Key Map Size", 
Integer.valueOf(this.keyStore.size()) ) );
 
-        try
+        if (this.dataFile != null)
         {
-            elems.add(new StatElement<Long>( "Data File Length",
-                    Long.valueOf(this.dataFile != null ? 
this.dataFile.length() : -1L) ) );
-        }
-        catch ( IOException e )
-        {
-            log.error( e );
-        }
+            try
+            {
+                elems.add(new StatElement<Long>( "Data File Length", 
Long.valueOf(this.dataFile.length()) ) );
+            }
+            catch ( IOException e )
+            {
+                log.error( e );
+            }
 
-        elems.add(new StatElement<Integer>( "Block Size Bytes",
-                Integer.valueOf(this.dataFile.getBlockSizeBytes()) ) );
-        elems.add(new StatElement<Integer>( "Number Of Blocks",
-                Integer.valueOf(this.dataFile.getNumberOfBlocks()) ) );
-        elems.add(new StatElement<Long>( "Average Put Size Bytes",
-                Long.valueOf(this.dataFile.getAveragePutSizeBytes()) ) );
-        elems.add(new StatElement<Integer>( "Empty Blocks",
-                Integer.valueOf(this.dataFile.getEmptyBlocks()) ) );
+            elems.add(new StatElement<Integer>( "Block Size Bytes",
+                    Integer.valueOf(this.dataFile.getBlockSizeBytes()) ) );
+            elems.add(new StatElement<Integer>( "Number Of Blocks",
+                    Integer.valueOf(this.dataFile.getNumberOfBlocks()) ) );
+            elems.add(new StatElement<Long>( "Average Put Size Bytes",
+                    Long.valueOf(this.dataFile.getAveragePutSizeBytes()) ) );
+            elems.add(new StatElement<Integer>( "Empty Blocks",
+                    Integer.valueOf(this.dataFile.getEmptyBlocks()) ) );
+        }
 
         // get the stats from the super too
         IStats sStats = super.getStatistics();

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
 Thu Dec  3 16:41:49 2015
@@ -370,7 +370,7 @@ public class BlockDiskKeyStore<K>
         /**
          * <code>tag</code> tells us which map we are working on.
          */
-        public final String tag = "orig-lru-size";
+        public final static String TAG = "orig-lru-size";
 
         // size of the content in kB
         private AtomicInteger contentSize;
@@ -489,7 +489,7 @@ public class BlockDiskKeyStore<K>
         /**
          * <code>tag</code> tells us which map we are working on.
          */
-        public final String tag = "orig-lru-count";
+        public final static String TAG = "orig-lru-count";
 
         public LRUMapCountLimited(int maxKeySize)
         {

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
 Thu Dec  3 16:41:49 2015
@@ -1692,7 +1692,7 @@ public class IndexedDiskCache<K, V> exte
         /**
          * <code>tag</code> tells us which map we are working on.
          */
-        public String tag = "orig";
+        public static final String TAG = "orig";
 
         // size of the content in kB
         private AtomicInteger contentSize;

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
 Thu Dec  3 16:41:49 2015
@@ -252,6 +252,8 @@ public class JDBCDiskCache<K, V>
     private boolean insertRow( ICacheElement<K, V> ce, Connection con, byte[] 
element )
     {
         boolean exists = false;
+        PreparedStatement psInsert = null;
+
         try
         {
             String sqlI = "insert into "
@@ -259,7 +261,7 @@ public class JDBCDiskCache<K, V>
                 + " (CACHE_KEY, REGION, ELEMENT, MAX_LIFE_SECONDS, IS_ETERNAL, 
CREATE_TIME, UPDATE_TIME_SECONDS, SYSTEM_EXPIRE_TIME_SECONDS) "
                 + " values (?, ?, ?, ?, ?, ?, ?, ?)";
 
-            PreparedStatement psInsert = con.prepareStatement( sqlI );
+            psInsert = con.prepareStatement( sqlI );
             psInsert.setString( 1, (String) ce.getKey() );
             psInsert.setString( 2, this.getCacheName() );
             psInsert.setBytes( 3, element );
@@ -282,7 +284,6 @@ public class JDBCDiskCache<K, V>
             psInsert.setLong( 8, expireTime );
 
             psInsert.execute();
-            psInsert.close();
         }
         catch ( SQLException e )
         {
@@ -301,6 +302,21 @@ public class JDBCDiskCache<K, V>
                 exists = doesElementExist( ce, con );
             }
         }
+        finally
+        {
+            if (psInsert != null)
+            {
+                try
+                {
+                    psInsert.close();
+                }
+                catch (SQLException e)
+                {
+                    log.error( "Problem closing statement.", e );
+                }
+            }
+        }
+
         return exists;
     }
 
@@ -314,12 +330,14 @@ public class JDBCDiskCache<K, V>
     private void updateRow( ICacheElement<K, V> ce, Connection con, byte[] 
element )
     {
         String sqlU = null;
+        PreparedStatement psUpdate = null;
+
         try
         {
             sqlU = "update " + getJdbcDiskCacheAttributes().getTableName()
                 + " set ELEMENT  = ?, CREATE_TIME = ?, UPDATE_TIME_SECONDS = 
?, " + " SYSTEM_EXPIRE_TIME_SECONDS = ? "
                 + " where CACHE_KEY = ? and REGION = ?";
-            PreparedStatement psUpdate = con.prepareStatement( sqlU );
+            psUpdate = con.prepareStatement( sqlU );
             psUpdate.setBytes( 1, element );
 
             Timestamp createTime = new Timestamp( 
ce.getElementAttributes().getCreateTime() );
@@ -334,7 +352,6 @@ public class JDBCDiskCache<K, V>
             psUpdate.setString( 5, (String) ce.getKey() );
             psUpdate.setString( 6, this.getCacheName() );
             psUpdate.execute();
-            psUpdate.close();
 
             if ( log.isDebugEnabled() )
             {
@@ -345,6 +362,20 @@ public class JDBCDiskCache<K, V>
         {
             log.error( "e2 sql [" + sqlU + "] Exception: ", e2 );
         }
+        finally
+        {
+            if (psUpdate != null)
+            {
+                try
+                {
+                    psUpdate.close();
+                }
+                catch (SQLException e)
+                {
+                    log.error( "Problem closing statement.", e );
+                }
+            }
+        }
     }
 
     /**
@@ -358,6 +389,8 @@ public class JDBCDiskCache<K, V>
     {
         boolean exists = false;
         PreparedStatement psSelect = null;
+        ResultSet rs = null;
+
         try
         {
             // don't select the element, since we want this to be fast.
@@ -368,7 +401,7 @@ public class JDBCDiskCache<K, V>
             psSelect.setString( 1, this.getCacheName() );
             psSelect.setString( 2, (String) ce.getKey() );
 
-            ResultSet rs = psSelect.executeQuery();
+            rs = psSelect.executeQuery();
 
             if ( rs.next() )
             {
@@ -379,8 +412,6 @@ public class JDBCDiskCache<K, V>
             {
                 log.debug( "[" + ce.getKey() + "] existing status is " + 
exists );
             }
-
-            rs.close();
         }
         catch ( SQLException e )
         {
@@ -390,14 +421,25 @@ public class JDBCDiskCache<K, V>
         {
             try
             {
+                if ( rs != null )
+                {
+                    rs.close();
+                }
+            }
+            catch ( SQLException e )
+            {
+                log.error( "Problem closing result set.", e );
+            }
+            try
+            {
                 if ( psSelect != null )
                 {
                     psSelect.close();
                 }
             }
-            catch ( SQLException e1 )
+            catch ( SQLException e )
             {
-                log.error( "Problem closing statement.", e1 );
+                log.error( "Problem closing statement.", e );
             }
         }
 
@@ -439,6 +481,7 @@ public class JDBCDiskCache<K, V>
             try
             {
                 PreparedStatement psSelect = null;
+
                 try
                 {
                     psSelect = con.prepareStatement( selectString );
@@ -446,6 +489,7 @@ public class JDBCDiskCache<K, V>
                     psSelect.setString( 2, key.toString() );
 
                     ResultSet rs = psSelect.executeQuery();
+
                     try
                     {
                         if ( rs.next() )

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
 Thu Dec  3 16:41:49 2015
@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHa
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
@@ -69,6 +70,9 @@ public class JDBCDiskCacheFactory
     /** Pool name to DataSourceFactories */
     private ConcurrentMap<String, DataSourceFactory> dsFactories;
 
+    /** Lock to allow lengthy initialization of DataSourceFactories */
+    private ReentrantLock dsFactoryLock;
+
     /** props prefix */
     protected static final String POOL_CONFIGURATION_PREFIX = 
"jcs.jdbcconnectionpool.";
 
@@ -115,6 +119,7 @@ public class JDBCDiskCacheFactory
         this.tableStates = new ConcurrentHashMap<String, TableState>();
         this.shrinkerThreadMap = new ConcurrentHashMap<String, 
ShrinkerThread>();
         this.dsFactories = new ConcurrentHashMap<String, DataSourceFactory>();
+        this.dsFactoryLock = new ReentrantLock();
     }
 
     /**
@@ -234,43 +239,56 @@ public class JDBCDiskCacheFactory
             poolName = cattr.getConnectionPoolName();
         }
 
-       synchronized (this.dsFactories)
+
+       DataSourceFactory dsFactory = this.dsFactories.get(poolName);
+
+       if (dsFactory == null)
        {
-               DataSourceFactory dsFactory = this.dsFactories.get(poolName);
+            dsFactoryLock.lock();
+
+            try
+            {
+                // double check
+                dsFactory = this.dsFactories.get(poolName);
+
+                if (dsFactory == null)
+                {
+                       JDBCDiskCacheAttributes dsConfig = null;
 
-               if (dsFactory == null)
-               {
-                       JDBCDiskCacheAttributes dsConfig = null;
-
-                       if (cattr.getConnectionPoolName() == null)
-                       {
-                               dsConfig = cattr;
-                   }
-                   else
-                   {
-                       dsConfig = new JDBCDiskCacheAttributes();
-                       String dsConfigAttributePrefix = 
POOL_CONFIGURATION_PREFIX + poolName + ATTRIBUTE_PREFIX;
-                       PropertySetter.setProperties( dsConfig,
-                                       configProps,
-                                       dsConfigAttributePrefix + "." );
-
-                       dsConfig.setConnectionPoolName(poolName);
-                   }
-
-                       if ( dsConfig.getJndiPath() != null )
-                       {
-                               dsFactory = new JndiDataSourceFactory();
-                       }
-                       else
-                       {
-                           dsFactory = new SharedPoolDataSourceFactory();
-                       }
-
-                       dsFactory.initialize(dsConfig);
-                       this.dsFactories.put(poolName, dsFactory);
-               }
+                       if (cattr.getConnectionPoolName() == null)
+                       {
+                               dsConfig = cattr;
+                    }
+                    else
+                    {
+                        dsConfig = new JDBCDiskCacheAttributes();
+                        String dsConfigAttributePrefix = 
POOL_CONFIGURATION_PREFIX + poolName + ATTRIBUTE_PREFIX;
+                        PropertySetter.setProperties( dsConfig,
+                                       configProps,
+                                       dsConfigAttributePrefix + "." );
+
+                        dsConfig.setConnectionPoolName(poolName);
+                    }
+
+                       if ( dsConfig.getJndiPath() != null )
+                       {
+                               dsFactory = new JndiDataSourceFactory();
+                       }
+                       else
+                       {
+                           dsFactory = new SharedPoolDataSourceFactory();
+                       }
 
-               return dsFactory;
+                       dsFactory.initialize(dsConfig);
+                       this.dsFactories.put(poolName, dsFactory);
+                }
+            }
+            finally
+            {
+                dsFactoryLock.unlock();
+            }
        }
+
+       return dsFactory;
     }
 }

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
 Thu Dec  3 16:41:49 2015
@@ -19,17 +19,15 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import java.io.Serializable;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheMonitor;
 import 
org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory;
 import 
org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
 import org.apache.commons.jcs.engine.CacheStatus;
 import org.apache.commons.jcs.engine.ZombieCacheServiceNonLocal;
 import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Used to monitor and repair any failed connection for the lateral cache 
service. By default the
@@ -38,19 +36,8 @@ import org.apache.commons.logging.LogFac
  * driven mode. That is, it attempts to recover the connections on a periodic 
basis. When all failed
  * connections are restored, it changes back to the failure driven mode.
  */
-public class LateralCacheMonitor extends Thread
+public class LateralCacheMonitor extends AbstractAuxiliaryCacheMonitor
 {
-    /** The logger */
-    private static final Log log = LogFactory.getLog( 
LateralCacheMonitor.class );
-
-    /** How long to wait between runs */
-    private static long idlePeriod = 20 * 1000;
-
-    /**
-     * Must make sure LateralCacheMonitor is started before any lateral error 
can be detected!
-     */
-    private boolean allright = true;
-
     /**
      * Map of caches to monitor
      */
@@ -62,30 +49,6 @@ public class LateralCacheMonitor extends
     private LateralTCPCacheFactory factory;
 
     /**
-     * shutdown flag
-     */
-    private boolean shutdown = false;
-
-    /** code for eror */
-    private static final int ERROR = 1;
-
-    /** The mode we are running in. Error driven */
-    private static int mode = ERROR;
-
-    /**
-     * Configures the idle period between repairs.
-     * <p>
-     * @param idlePeriod The new idlePeriod value
-     */
-    public static void setIdlePeriod( long idlePeriod )
-    {
-        if ( idlePeriod > LateralCacheMonitor.idlePeriod )
-        {
-            LateralCacheMonitor.idlePeriod = idlePeriod;
-        }
-    }
-
-    /**
      * Allows close classes, ie testers to set the idle period to something 
testable.
      * <p>
      * @param idlePeriod
@@ -107,6 +70,7 @@ public class LateralCacheMonitor extends
         super("JCS-LateralCacheMonitor");
         this.factory = factory;
         this.caches = new ConcurrentHashMap<String, LateralCacheNoWait<?,?>>();
+        setIdlePeriod(20000L);
     }
 
     /**
@@ -126,159 +90,46 @@ public class LateralCacheMonitor extends
     }
 
     /**
-     * Notifies the cache monitor that an error occurred, and kicks off the 
error recovery process.
-     */
-    public void notifyError()
-    {
-        bad();
-        synchronized ( this )
-        {
-            notify();
-        }
-    }
-
-    /**
-     * Notifies the cache monitor that the service shall shut down
+     * Clean up all resources before shutdown
      */
-    public void notifyShutdown()
+    @Override
+    public void dispose()
     {
-        synchronized ( this )
-        {
-            this.shutdown = true;
-            notify();
-        }
+        this.caches.clear();
     }
 
     /**
      * Main processing method for the LateralCacheMonitor object
      */
     @Override
-    public void run()
+    public void doWork()
     {
-        do
+        // Monitor each cache instance one after the other.
+        log.info( "Number of caches to monitor = " + caches.size() );
+        //for
+        for (Map.Entry<String, LateralCacheNoWait<?, ?>> entry : 
caches.entrySet())
         {
-            if ( mode == ERROR )
-            {
-                if ( log.isDebugEnabled() )
-                {
-                    if ( allright )
-                    {
-                        log.debug( "ERROR DRIVEN MODE: allright = " + allright
-                            + ", connection monitor will wait for an error." );
-                    }
-                    else
-                    {
-                        log.debug( "ERROR DRIVEN MODE: allright = " + allright 
+ " connection monitor running." );
-                    }
-                }
-
-                synchronized ( this )
-                {
-                    if ( allright )
-                    {
-                        // Failure driven mode.
-                        try
-                        {
-                            wait();
-                            // wake up only if there is an error.
-                        }
-                        catch ( InterruptedException ignore )
-                        {
-                            //no op, this is expected
-                        }
-                    }
-                }
-            }
-            else
-            {
-                log.debug( "TIME DRIVEN MODE: connection monitor will sleep 
for " + idlePeriod + " after this run." );
-                // Time driven mode: sleep between each round of recovery
-                // attempt.
-                // will need to test not just check status
-            }
+            String cacheName = entry.getKey();
 
-            // check for requested shutdown
-            synchronized ( this )
+            @SuppressWarnings("unchecked") // Downcast to match service
+            LateralCacheNoWait<Object, Object> c = (LateralCacheNoWait<Object, 
Object>) entry.getValue();
+            if ( c.getStatus() == CacheStatus.ERROR )
             {
-                if (shutdown)
-                {
-                    log.info( "Shutting down cache monitor" );
-                    this.caches.clear();
-                    return;
-                }
-            }
+                log.info( "Found LateralCacheNoWait in error, " + cacheName );
 
-            // The "allright" flag must be false here.
-            // Simply presume we can fix all the errors until proven otherwise.
-            synchronized ( this )
-            {
-                allright = true;
-            }
+                ITCPLateralCacheAttributes lca = 
(ITCPLateralCacheAttributes)c.getAuxiliaryCacheAttributes();
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Cache monitor running." );
-            }
-
-            // Monitor each cache instance one after the other.
-            log.info( "Number of caches to monitor = " + caches.size() );
-            //for
-            for (Map.Entry<String, LateralCacheNoWait<?, ?>> entry : 
caches.entrySet())
-            {
-                String cacheName = entry.getKey();
+                // Get service instance
+                ICacheServiceNonLocal<Object, Object> cacheService = 
factory.getCSNLInstance(lca);
 
-                @SuppressWarnings("unchecked") // Downcast to match service
-                LateralCacheNoWait<Serializable, Serializable> c =
-                        (LateralCacheNoWait<Serializable, Serializable>) 
entry.getValue();
-                if ( c.getStatus() == CacheStatus.ERROR )
+                // If we can't fix them, just skip and re-try in the
+                // next round.
+                if (cacheService instanceof ZombieCacheServiceNonLocal)
                 {
-                    log.info( "Found LateralCacheNoWait in error, " + 
cacheName );
-
-                    ITCPLateralCacheAttributes lca = 
(ITCPLateralCacheAttributes)c.getAuxiliaryCacheAttributes();
-
-                    // Get service instance
-                    ICacheServiceNonLocal<Serializable, Serializable> 
cacheService = factory.getCSNLInstance(lca);
-
-                    // If we can't fix them, just skip and re-try in the
-                    // next round.
-                    if (cacheService instanceof ZombieCacheServiceNonLocal)
-                    {
-                        continue;
-                    }
-
-                    c.fixCache(cacheService);
+                    continue;
                 }
-            }
-
-            try
-            {
-                // don't want to sleep after waking from an error
-                // run immediately and sleep here.
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Lateral cache monitor sleeping for " + 
idlePeriod + " between runs." );
-                }
-
-                Thread.sleep( idlePeriod );
-            }
-            catch ( InterruptedException ex )
-            {
-                // ignore;
-            }
-        }
-        while ( true );
-    }
 
-    /**
-     * Sets the "allright" flag to false in a critical section.
-     */
-    private void bad()
-    {
-        if ( allright )
-        {
-            synchronized ( this )
-            {
-                allright = false;
+                c.fixCache(cacheService);
             }
         }
     }

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
 Thu Dec  3 16:41:49 2015
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
@@ -63,6 +64,9 @@ public class LateralTCPCacheFactory
     /** Address to service map. */
     private ConcurrentHashMap<String, ICacheServiceNonLocal<?, ?>> 
csnlInstances;
 
+    /** Lock for initialization of address to service map */
+    private ReentrantLock csnlLock;
+
     /** Map of available discovery listener instances, keyed by port. */
     private ConcurrentHashMap<String, LateralTCPDiscoveryListener> 
lTCPDLInstances;
 
@@ -168,6 +172,7 @@ public class LateralTCPCacheFactory
     public void initialize()
     {
         this.csnlInstances = new ConcurrentHashMap<String, 
ICacheServiceNonLocal<?, ?>>();
+        this.csnlLock = new ReentrantLock();
         this.lTCPDLInstances = new ConcurrentHashMap<String, 
LateralTCPDiscoveryListener>();
 
         // Create the monitoring daemon thread
@@ -216,55 +221,68 @@ public class LateralTCPCacheFactory
      *
      * @return ICacheServiceNonLocal<K, V>
      */
+    // Need to cast because of common map for all cache services
+    @SuppressWarnings("unchecked")
     public <K, V> ICacheServiceNonLocal<K, V> getCSNLInstance( 
ITCPLateralCacheAttributes lca )
     {
         String key = lca.getTcpServer();
-        synchronized ( csnlInstances )
+
+        ICacheServiceNonLocal<K, V> service = (ICacheServiceNonLocal<K, 
V>)csnlInstances.get( key );
+
+        if ( service == null || service instanceof ZombieCacheServiceNonLocal )
         {
-            // Need to cast because of common map for all cache services
-            @SuppressWarnings("unchecked")
-            ICacheServiceNonLocal<K, V> service = (ICacheServiceNonLocal<K, 
V>)csnlInstances.get( key );
+            csnlLock.lock();
 
-            // If service creation did not succeed last time, force retry
-            if ( service instanceof ZombieCacheServiceNonLocal)
+            try
             {
-                service = null;
-                log.info("Disposing of zombie service instance for [" + key + 
"]");
-            }
+                // double check
+                service = (ICacheServiceNonLocal<K, V>)csnlInstances.get( key 
);
 
-            if ( service == null )
-            {
-                log.info( "Instance for [" + key + "] is null, creating" );
+                // If service creation did not succeed last time, force retry
+                if ( service instanceof ZombieCacheServiceNonLocal)
+                {
+                    service = null;
+                    log.info("Disposing of zombie service instance for [" + 
key + "]");
+                }
 
-                // Create the service
-                try
+                if ( service == null )
                 {
-                    if ( log.isInfoEnabled() )
+                    log.info( "Instance for [" + key + "] is null, creating" );
+
+                    // Create the service
+                    try
                     {
-                        log.info( "Creating TCP service, lca = " + lca );
+                        if ( log.isInfoEnabled() )
+                        {
+                            log.info( "Creating TCP service, lca = " + lca );
+                        }
+
+                        service = new LateralTCPService<K, V>( lca );
+                    }
+                    catch ( IOException ex )
+                    {
+                        // Failed to connect to the lateral server.
+                        // Configure this LateralCacheManager instance to use 
the
+                        // "zombie" services.
+                        log.error( "Failure, lateral instance will use zombie 
service", ex );
+
+                        service = new ZombieCacheServiceNonLocal<K, V>( 
lca.getZombieQueueMaxSize() );
+
+                        // Notify the cache monitor about the error, and kick 
off
+                        // the recovery process.
+                        monitor.notifyError();
                     }
 
-                    service = new LateralTCPService<K, V>( lca );
+                    csnlInstances.put( key, service );
                 }
-                catch ( IOException ex )
-                {
-                    // Failed to connect to the lateral server.
-                    // Configure this LateralCacheManager instance to use the
-                    // "zombie" services.
-                    log.error( "Failure, lateral instance will use zombie 
service", ex );
-
-                    service = new ZombieCacheServiceNonLocal<K, V>( 
lca.getZombieQueueMaxSize() );
-
-                    // Notify the cache monitor about the error, and kick off
-                    // the recovery process.
-                    monitor.notifyError();
-                }
-
-                csnlInstances.put( key, service );
             }
-
-            return service;
+            finally
+            {
+                csnlLock.unlock();
+            }
         }
+
+        return service;
     }
 
     /**

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
 Thu Dec  3 16:41:49 2015
@@ -19,6 +19,10 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpMethod;
 import org.apache.commons.httpclient.HttpState;
@@ -32,10 +36,6 @@ import org.apache.commons.jcs.utils.seri
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
 /** Calls the service. */
 public class RemoteHttpCacheDispatcher
     extends AbstractHttpClient
@@ -129,7 +129,7 @@ public class RemoteHttpCacheDispatcher
      */
     protected <K, V> String addParameters( RemoteCacheRequest<K, V> 
remoteCacheRequest, String baseUrl )
     {
-        StringBuilder url = new StringBuilder( baseUrl );
+        StringBuilder url = new StringBuilder( baseUrl == null ? "" : baseUrl 
);
 
         try
         {

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
 Thu Dec  3 16:41:49 2015
@@ -31,6 +31,8 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.commons.jcs.access.exception.CacheException;
 import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheListener;
@@ -82,21 +84,21 @@ public class RemoteCacheServer<K, V>
     private int puts = 0;
 
     /** Maps cache name to CacheListeners object. association of listeners 
(regions). */
-    private final Map<String, CacheListeners<K, V>> cacheListenersMap =
+    private final transient ConcurrentMap<String, CacheListeners<K, V>> 
cacheListenersMap =
         new ConcurrentHashMap<String, CacheListeners<K, V>>();
 
     /** maps cluster listeners to regions. */
-    private final Map<String, CacheListeners<K, V>> clusterListenersMap =
+    private final transient ConcurrentMap<String, CacheListeners<K, V>> 
clusterListenersMap =
         new ConcurrentHashMap<String, CacheListeners<K, V>>();
 
     /** The central hub */
     private transient CompositeCacheManager cacheManager;
 
     /** relates listener id with a type */
-    private final Map<Long, RemoteType> idTypeMap = new 
ConcurrentHashMap<Long, RemoteType>();
+    private final ConcurrentMap<Long, RemoteType> idTypeMap = new 
ConcurrentHashMap<Long, RemoteType>();
 
     /** relates listener id with an ip address */
-    private final Map<Long, String> idIPMap = new ConcurrentHashMap<Long, 
String>();
+    private final ConcurrentMap<Long, String> idIPMap = new 
ConcurrentHashMap<Long, String>();
 
     /** Used to get the next listener id. */
     private final int[] listenerId = new int[1];
@@ -111,6 +113,12 @@ public class RemoteCacheServer<K, V>
     /** An optional event logger */
     private transient ICacheEventLogger cacheEventLogger;
 
+    /** Lock for Cache listener initialization */
+    private ReentrantLock cacheListenersLock = new ReentrantLock();
+
+    /** Lock for Cluster listener initialization */
+    private ReentrantLock clusterListenersLock = new ReentrantLock();
+
     /**
      * Constructor for the RemoteCacheServer object. This initializes the 
server with the values
      * from the config file.
@@ -1145,19 +1153,16 @@ public class RemoteCacheServer<K, V>
     public void release()
         throws IOException
     {
-        synchronized ( cacheListenersMap )
+        for (CacheListeners<K, V> cacheDesc : cacheListenersMap.values())
         {
-            for (CacheListeners<K, V> cacheDesc : cacheListenersMap.values())
-            {
-                ICacheEventQueue<K, V>[] qlist = getEventQList( cacheDesc, 0 );
+            ICacheEventQueue<K, V>[] qlist = getEventQList( cacheDesc, 0 );
 
-                for ( int i = 0; i < qlist.length; i++ )
-                {
-                    qlist[i].addDisposeEvent();
-                }
+            for ( int i = 0; i < qlist.length; i++ )
+            {
+                qlist[i].addDisposeEvent();
             }
-            cacheManager.release();
         }
+        cacheManager.release();
     }
 
     /**
@@ -1170,10 +1175,14 @@ public class RemoteCacheServer<K, V>
     protected CacheListeners<K, V> getCacheListeners( String cacheName )
     {
         CacheListeners<K, V> cacheListeners = cacheListenersMap.get( cacheName 
);
-        synchronized ( cacheListenersMap )
+
+        if ( cacheListeners == null )
         {
-            if ( cacheListeners == null )
+            cacheListenersLock.lock();
+
+            try
             {
+                // double check
                 cacheListeners = cacheListenersMap.get( cacheName );
                 if ( cacheListeners == null )
                 {
@@ -1182,7 +1191,12 @@ public class RemoteCacheServer<K, V>
                     cacheListenersMap.put( cacheName, cacheListeners );
                 }
             }
+            finally
+            {
+                cacheListenersLock.unlock();
+            }
         }
+
         return cacheListeners;
     }
 
@@ -1196,9 +1210,12 @@ public class RemoteCacheServer<K, V>
     protected CacheListeners<K, V> getClusterListeners( String cacheName )
     {
         CacheListeners<K, V> cacheListeners = clusterListenersMap.get( 
cacheName );
-        synchronized ( clusterListenersMap )
+
+        if ( cacheListeners == null )
         {
-            if ( cacheListeners == null )
+            clusterListenersLock.lock();
+
+            try
             {
                 cacheListeners = clusterListenersMap.get( cacheName );
                 if ( cacheListeners == null )
@@ -1208,7 +1225,12 @@ public class RemoteCacheServer<K, V>
                     clusterListenersMap.put( cacheName, cacheListeners );
                 }
             }
+            finally
+            {
+                clusterListenersLock.unlock();
+            }
         }
+
         return cacheListeners;
     }
 
@@ -1227,11 +1249,7 @@ public class RemoteCacheServer<K, V>
     @SuppressWarnings("unchecked") // No generic arrays in java
     private ICacheEventQueue<K, V>[] getEventQList( CacheListeners<K, V> 
cacheListeners, long requesterId )
     {
-        ICacheEventQueue<K, V>[] list = null;
-        synchronized ( cacheListeners.eventQMap )
-        {
-            list = cacheListeners.eventQMap.values().toArray( new 
ICacheEventQueue[0] );
-        }
+        ICacheEventQueue<K, V>[] list = 
cacheListeners.eventQMap.values().toArray( new ICacheEventQueue[0] );
         int count = 0;
         // Set those not qualified to null; Count those qualified.
         for ( int i = 0; i < list.length; i++ )

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheListeners.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheListeners.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheListeners.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheListeners.java
 Thu Dec  3 16:41:49 2015
@@ -19,12 +19,13 @@ package org.apache.commons.jcs.engine;
  * under the License.
  */
 
-import org.apache.commons.jcs.engine.behavior.ICache;
-import org.apache.commons.jcs.engine.behavior.ICacheEventQueue;
-
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.jcs.engine.behavior.ICache;
+import org.apache.commons.jcs.engine.behavior.ICacheEventQueue;
 
 /**
  * Used to associates a set of [cache listener to cache event queue] for a
@@ -36,7 +37,7 @@ public class CacheListeners<K, V>
     public final ICache<K, V> cache;
 
     /** Map ICacheListener to ICacheEventQueue */
-    public final Map<Long, ICacheEventQueue<K, V>> eventQMap =
+    public final ConcurrentMap<Long, ICacheEventQueue<K, V>> eventQMap =
         new ConcurrentHashMap<Long, ICacheEventQueue<K, V>>();
 
     /**

Modified: 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java?rev=1717801&r1=1717800&r2=1717801&view=diff
==============================================================================
--- 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
 (original)
+++ 
commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
 Thu Dec  3 16:41:49 2015
@@ -28,6 +28,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.commons.jcs.access.exception.CacheException;
 import org.apache.commons.jcs.access.exception.ObjectNotFoundException;
@@ -82,7 +84,7 @@ public class CompositeCache<K, V>
     private AuxiliaryCache<K, V>[] auxCaches = new AuxiliaryCache[0];
 
     /** is this alive? */
-    private boolean alive = true;
+    private AtomicBoolean alive;
 
     /** Region Elemental Attributes, default. */
     private IElementAttributes attr;
@@ -91,22 +93,22 @@ public class CompositeCache<K, V>
     private ICompositeCacheAttributes cacheAttr;
 
     /** How many times update was called. */
-    private int updateCount;
+    private AtomicInteger updateCount;
 
     /** How many times remove was called. */
-    private int removeCount;
+    private AtomicInteger removeCount;
 
     /** Memory cache hit count */
-    private int hitCountRam;
+    private AtomicInteger hitCountRam;
 
     /** Auxiliary cache hit count (number of times found in ANY auxiliary) */
-    private int hitCountAux;
+    private AtomicInteger hitCountAux;
 
     /** Count of misses where element was not found. */
-    private int missCountNotFound = 0;
+    private AtomicInteger missCountNotFound;
 
     /** Count of misses where element was expired. */
-    private int missCountExpired = 0;
+    private AtomicInteger missCountExpired;
 
     /**
      * The cache hub can only have one memory cache. This could be made more 
flexible in the future,
@@ -127,6 +129,13 @@ public class CompositeCache<K, V>
     {
         this.attr = attr;
         this.cacheAttr = cattr;
+        this.alive = new AtomicBoolean(true);
+        this.updateCount = new AtomicInteger(0);
+        this.removeCount = new AtomicInteger(0);
+        this.hitCountRam = new AtomicInteger(0);
+        this.hitCountAux = new AtomicInteger(0);
+        this.missCountNotFound = new AtomicInteger(0);
+        this.missCountExpired = new AtomicInteger(0);
 
         createMemoryCache( cattr );
 
@@ -233,16 +242,15 @@ public class CompositeCache<K, V>
             log.debug( "Updating memory cache " + cacheElement.getKey() );
         }
 
+        updateCount.incrementAndGet();
+
         synchronized ( this )
         {
-            updateCount++;
-
             memCache.update( cacheElement );
-
             updateAuxiliaries( cacheElement, localOnly );
-
-            cacheElement.getElementAttributes().setLastAccessTimeNow();
         }
+
+        cacheElement.getElementAttributes().setLastAccessTimeNow();
     }
 
     /**
@@ -270,7 +278,6 @@ public class CompositeCache<K, V>
         // more can be added if future auxiliary caches don't fit the model
         // You could run a database cache as either a remote or a local disk.
         // The types would describe the purpose.
-
         if ( log.isDebugEnabled() )
         {
             if ( auxCaches.length > 0 )
@@ -283,85 +290,88 @@ public class CompositeCache<K, V>
             }
         }
 
-        for ( int i = 0; i < auxCaches.length; i++ )
+        for ( ICache<K, V> aux : auxCaches )
         {
-            ICache<K, V> aux = auxCaches[i];
-
-            if ( log.isDebugEnabled() )
+            if ( aux == null )
             {
-                log.debug( "Auxilliary cache type: " + aux.getCacheType() );
+                continue;
             }
 
-            if ( aux == null )
+            if ( log.isDebugEnabled() )
             {
-                continue;
+                log.debug( "Auxiliary cache type: " + aux.getCacheType() );
             }
 
-            // SEND TO REMOTE STORE
-            if ( aux.getCacheType() == CacheType.REMOTE_CACHE )
+            switch (aux.getCacheType())
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "ce.getElementAttributes().getIsRemote() = "
-                        + cacheElement.getElementAttributes().getIsRemote() );
-                }
+                // SEND TO REMOTE STORE
+                case REMOTE_CACHE:
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "ce.getElementAttributes().getIsRemote() = "
+                            + 
cacheElement.getElementAttributes().getIsRemote() );
+                    }
 
-                if ( cacheElement.getElementAttributes().getIsRemote() && 
!localOnly )
-                {
-                    try
+                    if ( cacheElement.getElementAttributes().getIsRemote() && 
!localOnly )
                     {
-                        // need to make sure the group cache understands that
-                        // the key is a group attribute on update
-                        aux.update( cacheElement );
-                        if ( log.isDebugEnabled() )
+                        try
                         {
-                            log.debug( "Updated remote store for " + 
cacheElement.getKey() + cacheElement );
+                            // need to make sure the group cache understands 
that
+                            // the key is a group attribute on update
+                            aux.update( cacheElement );
+                            if ( log.isDebugEnabled() )
+                            {
+                                log.debug( "Updated remote store for " + 
cacheElement.getKey() + cacheElement );
+                            }
+                        }
+                        catch ( IOException ex )
+                        {
+                            log.error( "Failure in updateExclude", ex );
                         }
                     }
-                    catch ( IOException ex )
-                    {
-                        log.error( "Failure in updateExclude", ex );
-                    }
-                }
+                    break;
+
                 // SEND LATERALLY
-            }
-            else if ( aux.getCacheType() == CacheType.LATERAL_CACHE )
-            {
-                // lateral can't do the checking since it is dependent on the
-                // cache region restrictions
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "lateralcache in aux list: cattr " + 
cacheAttr.isUseLateral() );
-                }
-                if ( cacheAttr.isUseLateral() && 
cacheElement.getElementAttributes().getIsLateral() && !localOnly )
-                {
-                    // DISTRIBUTE LATERALLY
-                    // Currently always multicast even if the value is
-                    // unchanged, to cause the cache item to move to the front.
-                    aux.update( cacheElement );
+                case LATERAL_CACHE:
+                    // lateral can't do the checking since it is dependent on 
the
+                    // cache region restrictions
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( "updated lateral cache for " + 
cacheElement.getKey() );
+                        log.debug( "lateralcache in aux list: cattr " + 
cacheAttr.isUseLateral() );
                     }
-                }
-            }
-            // update disk if the usage pattern permits
-            else if ( aux.getCacheType() == CacheType.DISK_CACHE )
-            {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "diskcache in aux list: cattr " + 
cacheAttr.isUseDisk() );
-                }
-                if ( cacheAttr.isUseDisk()
-                    && cacheAttr.getDiskUsagePattern() == 
DiskUsagePattern.UPDATE
-                    && cacheElement.getElementAttributes().getIsSpool() )
-                {
-                    aux.update( cacheElement );
+                    if ( cacheAttr.isUseLateral() && 
cacheElement.getElementAttributes().getIsLateral() && !localOnly )
+                    {
+                        // DISTRIBUTE LATERALLY
+                        // Currently always multicast even if the value is
+                        // unchanged, to cause the cache item to move to the 
front.
+                        aux.update( cacheElement );
+                        if ( log.isDebugEnabled() )
+                        {
+                            log.debug( "updated lateral cache for " + 
cacheElement.getKey() );
+                        }
+                    }
+                    break;
+
+                // update disk if the usage pattern permits
+                case DISK_CACHE:
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( "updated disk cache for " + 
cacheElement.getKey() );
+                        log.debug( "diskcache in aux list: cattr " + 
cacheAttr.isUseDisk() );
                     }
-                }
+                    if ( cacheAttr.isUseDisk()
+                        && cacheAttr.getDiskUsagePattern() == 
DiskUsagePattern.UPDATE
+                        && cacheElement.getElementAttributes().getIsSpool() )
+                    {
+                        aux.update( cacheElement );
+                        if ( log.isDebugEnabled() )
+                        {
+                            log.debug( "updated disk cache for " + 
cacheElement.getKey() );
+                        }
+                    }
+                    break;
+
+                default: // CACHE_HUB
+                    break;
             }
         }
     }
@@ -388,10 +398,8 @@ public class CompositeCache<K, V>
         boolean diskAvailable = false;
 
         // SPOOL TO DISK.
-        for ( int i = 0; i < auxCaches.length; i++ )
+        for ( ICache<K, V> aux : auxCaches )
         {
-            ICache<K, V> aux = auxCaches[i];
-
             if ( aux != null && aux.getCacheType() == CacheType.DISK_CACHE )
             {
                 diskAvailable = true;
@@ -410,20 +418,17 @@ public class CompositeCache<K, V>
                         log.error( "Problem spooling item to disk cache.", ex 
);
                         throw new IllegalStateException( ex.getMessage() );
                     }
-                    catch ( Exception oee )
-                    {
-                        // swallow
-                    }
+
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( "spoolToDisk done for: " + ce.getKey() + " 
on disk cache[" + i + "]" );
+                        log.debug( "spoolToDisk done for: " + ce.getKey() + " 
on disk cache[" + aux.getCacheName() + "]" );
                     }
                 }
                 else
                 {
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( "DiskCache avaialbe, but JCS is not 
configured to use the DiskCache as a swap." );
+                        log.debug( "DiskCache available, but JCS is not 
configured to use the DiskCache as a swap." );
                     }
                 }
             }
@@ -505,10 +510,8 @@ public class CompositeCache<K, V>
                             log.debug( cacheAttr.getCacheName() + " - Memory 
cache hit, but element expired" );
                         }
 
-                        missCountExpired++;
-
+                        missCountExpired.incrementAndGet();
                         remove( key );
-
                         element = null;
                     }
                     else
@@ -519,7 +522,7 @@ public class CompositeCache<K, V>
                         }
 
                         // Update counters
-                        hitCountRam++;
+                        hitCountRam.incrementAndGet();
                     }
 
                     found = true;
@@ -528,11 +531,8 @@ public class CompositeCache<K, V>
                 {
                     // Item not found in memory. If local invocation look in 
aux
                     // caches, even if not local look in disk auxiliaries
-
-                    for ( int i = 0; i < auxCaches.length; i++ )
+                    for (AuxiliaryCache<K, V> aux : auxCaches)
                     {
-                        AuxiliaryCache<K, V> aux = auxCaches[i];
-
                         if ( aux != null )
                         {
                             CacheType cacheType = aux.getCacheType();
@@ -567,28 +567,27 @@ public class CompositeCache<K, V>
                                 {
                                     if ( log.isDebugEnabled() )
                                     {
-                                        log.debug( cacheAttr.getCacheName() + 
" - Aux cache[" + i + "] hit, but element expired." );
+                                        log.debug( cacheAttr.getCacheName() + 
" - Aux cache[" + aux.getCacheName() + "] hit, but element expired." );
                                     }
 
-                                    missCountExpired++;
+                                    missCountExpired.incrementAndGet();
 
                                     // This will tell the remotes to remove 
the item
                                     // based on the element's expiration 
policy. The elements attributes
                                     // associated with the item when it 
created govern its behavior
                                     // everywhere.
                                     remove( key );
-
                                     element = null;
                                 }
                                 else
                                 {
                                     if ( log.isDebugEnabled() )
                                     {
-                                        log.debug( cacheAttr.getCacheName() + 
" - Aux cache[" + i + "] hit" );
+                                        log.debug( cacheAttr.getCacheName() + 
" - Aux cache[" + aux.getCacheName() + "] hit" );
                                     }
 
                                     // Update counters
-                                    hitCountAux++;
+                                    hitCountAux.incrementAndGet();
                                     copyAuxiliaryRetrievedItemToMemory( 
element );
                                 }
 
@@ -600,7 +599,7 @@ public class CompositeCache<K, V>
                     }
                 }
             }
-            catch ( Exception e )
+            catch ( IOException e )
             {
                 log.error( "Problem encountered getting element.", e );
             }
@@ -608,7 +607,7 @@ public class CompositeCache<K, V>
 
         if ( !found )
         {
-            missCountNotFound++;
+            missCountNotFound.incrementAndGet();
 
             if ( log.isDebugEnabled() )
             {
@@ -683,7 +682,7 @@ public class CompositeCache<K, V>
                 elements.putAll( getMultipleFromAuxiliaryCaches( 
remainingKeys, localOnly ) );
             }
         }
-        catch ( Exception e )
+        catch ( IOException e )
         {
             log.error( "Problem encountered getting elements.", e );
         }
@@ -691,7 +690,7 @@ public class CompositeCache<K, V>
         // if we didn't find all the elements, increment the miss count by the 
number of elements not found
         if ( elements.size() != keys.size() )
         {
-            missCountNotFound += keys.size() - elements.size();
+            missCountNotFound.addAndGet(keys.size() - elements.size());
 
             if ( log.isDebugEnabled() )
             {
@@ -730,8 +729,7 @@ public class CompositeCache<K, V>
                         log.debug( cacheAttr.getCacheName() + " - Memory cache 
hit, but element expired" );
                     }
 
-                    missCountExpired++;
-
+                    missCountExpired.incrementAndGet();
                     remove( element.getKey() );
                     elementsFromMemory.remove( element.getKey() );
                 }
@@ -743,7 +741,7 @@ public class CompositeCache<K, V>
                     }
 
                     // Update counters
-                    hitCountRam++;
+                    hitCountRam.incrementAndGet();
                 }
             }
         }
@@ -764,10 +762,8 @@ public class CompositeCache<K, V>
         Map<K, ICacheElement<K, V>> elements = new HashMap<K, ICacheElement<K, 
V>>();
         Set<K> remainingKeys = new HashSet<K>( keys );
 
-        for ( int i = 0; i < auxCaches.length; i++ )
+        for ( AuxiliaryCache<K, V> aux : auxCaches )
         {
-            AuxiliaryCache<K, V> aux = auxCaches[i];
-
             if ( aux != null )
             {
                 Map<K, ICacheElement<K, V>> elementsFromAuxiliary =
@@ -798,7 +794,7 @@ public class CompositeCache<K, V>
                     log.debug( "Got CacheElements: " + elementsFromAuxiliary );
                 }
 
-                processRetrievedElements( i, elementsFromAuxiliary );
+                processRetrievedElements( aux, elementsFromAuxiliary );
 
                 elements.putAll( elementsFromAuxiliary );
 
@@ -952,7 +948,7 @@ public class CompositeCache<K, V>
                         log.debug( "Got CacheElements: " + 
elementsFromAuxiliary );
                     }
 
-                    processRetrievedElements( i, elementsFromAuxiliary );
+                    processRetrievedElements( aux, elementsFromAuxiliary );
 
                     elements.putAll( elementsFromAuxiliary );
                 }
@@ -965,11 +961,11 @@ public class CompositeCache<K, V>
     /**
      * Remove expired elements retrieved from an auxiliary. Update memory with 
good items.
      * <p>
-     * @param i - the aux index
+     * @param aux the auxiliary cache instance
      * @param elementsFromAuxiliary
      * @throws IOException
      */
-    private void processRetrievedElements( int i, Map<K, ICacheElement<K, V>> 
elementsFromAuxiliary )
+    private void processRetrievedElements( AuxiliaryCache<K, V> aux, Map<K, 
ICacheElement<K, V>> elementsFromAuxiliary )
         throws IOException
     {
         Iterator<ICacheElement<K, V>> elementFromAuxiliaryIterator = new 
HashMap<K, ICacheElement<K, V>>( elementsFromAuxiliary ).values().iterator();
@@ -985,10 +981,10 @@ public class CompositeCache<K, V>
                 {
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( cacheAttr.getCacheName() + " - Aux cache[" 
+ i + "] hit, but element expired." );
+                        log.debug( cacheAttr.getCacheName() + " - Aux cache[" 
+ aux.getCacheName() + "] hit, but element expired." );
                     }
 
-                    missCountExpired++;
+                    missCountExpired.incrementAndGet();
 
                     // This will tell the remote caches to remove the item
                     // based on the element's expiration policy. The elements 
attributes
@@ -1001,11 +997,11 @@ public class CompositeCache<K, V>
                 {
                     if ( log.isDebugEnabled() )
                     {
-                        log.debug( cacheAttr.getCacheName() + " - Aux cache[" 
+ i + "] hit" );
+                        log.debug( cacheAttr.getCacheName() + " - Aux cache[" 
+ aux.getCacheName() + "] hit" );
                     }
 
                     // Update counters
-                    hitCountAux++;
+                    hitCountAux.incrementAndGet();
                     copyAuxiliaryRetrievedItemToMemory( element );
                 }
             }
@@ -1077,9 +1073,8 @@ public class CompositeCache<K, V>
         HashSet<K> allKeys = new HashSet<K>();
 
         allKeys.addAll( memCache.getKeySet() );
-        for ( int i = 0; i < auxCaches.length; i++ )
+        for ( AuxiliaryCache<K, V> aux : auxCaches )
         {
-            AuxiliaryCache<K, V> aux = auxCaches[i];
             if ( aux != null )
             {
                 if(!localOnly || aux.getCacheType() == CacheType.DISK_CACHE)
@@ -1139,60 +1134,61 @@ public class CompositeCache<K, V>
      * @param localOnly
      * @return true if the item was in the cache, else false
      */
-    protected synchronized boolean remove( K key, boolean localOnly )
+    protected boolean remove( K key, boolean localOnly )
     {
-        // not thread safe, but just for debugging and testing.
-        removeCount++;
+        removeCount.incrementAndGet();
 
         boolean removed = false;
 
-        try
-        {
-            removed = memCache.remove( key );
-        }
-        catch ( IOException e )
-        {
-            log.error( e );
-        }
-
-        // Removes from all auxiliary caches.
-        for ( int i = 0; i < auxCaches.length; i++ )
+        synchronized (this)
         {
-            ICache<K, V> aux = auxCaches[i];
-
-            if ( aux == null )
+            try
             {
-                continue;
+                removed = memCache.remove( key );
             }
-
-            CacheType cacheType = aux.getCacheType();
-
-            // for now let laterals call remote remove but not vice versa
-
-            if ( localOnly && ( cacheType == CacheType.REMOTE_CACHE || 
cacheType == CacheType.LATERAL_CACHE ) )
+            catch ( IOException e )
             {
-                continue;
+                log.error( e );
             }
-            try
+
+            // Removes from all auxiliary caches.
+            for ( ICache<K, V> aux : auxCaches )
             {
-                if ( log.isDebugEnabled() )
+                if ( aux == null )
                 {
-                    log.debug( "Removing " + key + " from cacheType" + 
cacheType );
+                    continue;
                 }
 
-                boolean b = aux.remove( key );
+                CacheType cacheType = aux.getCacheType();
+
+                // for now let laterals call remote remove but not vice versa
 
-                // Don't take the remote removal into account.
-                if ( !removed && cacheType != CacheType.REMOTE_CACHE )
+                if ( localOnly && ( cacheType == CacheType.REMOTE_CACHE || 
cacheType == CacheType.LATERAL_CACHE ) )
                 {
-                    removed = b;
+                    continue;
+                }
+                try
+                {
+                    if ( log.isDebugEnabled() )
+                    {
+                        log.debug( "Removing " + key + " from cacheType" + 
cacheType );
+                    }
+
+                    boolean b = aux.remove( key );
+
+                    // Don't take the remote removal into account.
+                    if ( !removed && cacheType != CacheType.REMOTE_CACHE )
+                    {
+                        removed = b;
+                    }
+                }
+                catch ( IOException ex )
+                {
+                    log.error( "Failure removing from aux", ex );
                 }
-            }
-            catch ( IOException ex )
-            {
-                log.error( "Failure removing from aux", ex );
             }
         }
+
         return removed;
     }
 
@@ -1227,42 +1223,43 @@ public class CompositeCache<K, V>
      *            looping.
      * @throws IOException
      */
-    protected synchronized void removeAll( boolean localOnly )
+    protected void removeAll( boolean localOnly )
         throws IOException
     {
-        try
+        synchronized (this)
         {
-            memCache.removeAll();
+            try
+            {
+                memCache.removeAll();
 
-            if ( log.isDebugEnabled() )
+                if ( log.isDebugEnabled() )
+                {
+                    log.debug( "Removed All keys from the memory cache." );
+                }
+            }
+            catch ( IOException ex )
             {
-                log.debug( "Removed All keys from the memory cache." );
+                log.error( "Trouble updating memory cache.", ex );
             }
-        }
-        catch ( IOException ex )
-        {
-            log.error( "Trouble updating memory cache.", ex );
-        }
-
-        // Removes from all auxiliary disk caches.
-        for ( int i = 0; i < auxCaches.length; i++ )
-        {
-            ICache<K, V> aux = auxCaches[i];
 
-            if ( aux != null && ( aux.getCacheType() == CacheType.DISK_CACHE 
|| !localOnly ) )
+            // Removes from all auxiliary disk caches.
+            for ( ICache<K, V> aux : auxCaches )
             {
-                try
+                if ( aux != null && ( aux.getCacheType() == 
CacheType.DISK_CACHE || !localOnly ) )
                 {
-                    if ( log.isDebugEnabled() )
+                    try
                     {
-                        log.debug( "Removing All keys from cacheType" + 
aux.getCacheType() );
-                    }
+                        if ( log.isDebugEnabled() )
+                        {
+                            log.debug( "Removing All keys from cacheType" + 
aux.getCacheType() );
+                        }
 
-                    aux.removeAll();
-                }
-                catch ( IOException ex )
-                {
-                    log.error( "Failure removing all from aux", ex );
+                        aux.removeAll();
+                    }
+                    catch ( IOException ex )
+                    {
+                        log.error( "Failure removing all from aux", ex );
+                    }
                 }
             }
         }
@@ -1284,7 +1281,7 @@ public class CompositeCache<K, V>
      * <p>
      * @param fromRemote
      */
-    public synchronized void dispose( boolean fromRemote )
+    public void dispose( boolean fromRemote )
     {
         if ( log.isInfoEnabled() )
         {
@@ -1292,88 +1289,85 @@ public class CompositeCache<K, V>
         }
 
         // If already disposed, return immediately
-        if ( !alive )
+        if ( alive.compareAndSet(true, false) == false )
         {
             return;
         }
-        alive = false;
 
-        // Now, shut down the event queue
-        if (elementEventQ != null)
-        {
-            elementEventQ.dispose();
-            elementEventQ = null;
-        }
-
-        // Dispose of each auxiliary cache, Remote auxiliaries will be
-        // skipped if 'fromRemote' is true.
-        for ( int i = 0; i < auxCaches.length; i++ )
+        synchronized (this)
         {
-            try
+            // Now, shut down the event queue
+            if (elementEventQ != null)
             {
-                ICache<K, V> aux = auxCaches[i];
-
-                // Skip this auxiliary if:
-                // - The auxiliary is null
-                // - The auxiliary is not alive
-                // - The auxiliary is remote and the invocation was remote
+                elementEventQ.dispose();
+                elementEventQ = null;
+            }
 
-                if ( aux == null || aux.getStatus() != CacheStatus.ALIVE
-                    || ( fromRemote && aux.getCacheType() == 
CacheType.REMOTE_CACHE ) )
+            // Dispose of each auxiliary cache, Remote auxiliaries will be
+            // skipped if 'fromRemote' is true.
+            for ( ICache<K, V> aux : auxCaches )
+            {
+                try
                 {
+                    // Skip this auxiliary if:
+                    // - The auxiliary is null
+                    // - The auxiliary is not alive
+                    // - The auxiliary is remote and the invocation was remote
+                    if ( aux == null || aux.getStatus() != CacheStatus.ALIVE
+                        || ( fromRemote && aux.getCacheType() == 
CacheType.REMOTE_CACHE ) )
+                    {
+                        if ( log.isInfoEnabled() )
+                        {
+                            log.info( "In DISPOSE, [" + 
this.cacheAttr.getCacheName() + "] SKIPPING auxiliary [" + aux.getCacheName() + 
"] fromRemote ["
+                                + fromRemote + "]" );
+                        }
+                        continue;
+                    }
+
                     if ( log.isInfoEnabled() )
                     {
-                        log.info( "In DISPOSE, [" + 
this.cacheAttr.getCacheName() + "] SKIPPING auxiliary [" + aux.getCacheName() + 
"] fromRemote ["
-                            + fromRemote + "]" );
+                        log.info( "In DISPOSE, [" + 
this.cacheAttr.getCacheName() + "] auxiliary [" + aux.getCacheName() + "]" );
                     }
-                    continue;
-                }
 
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "In DISPOSE, [" + this.cacheAttr.getCacheName() 
+ "] auxiliary [" + aux.getCacheName() + "]" );
-                }
+                    // IT USED TO BE THE CASE THAT (If the auxiliary is not a 
lateral, or the cache
+                    // attributes
+                    // have 'getUseLateral' set, all the elements currently in
+                    // memory are written to the lateral before disposing)
+                    // I changed this. It was excessive. Only the disk cache 
needs the items, since only
+                    // the disk cache is in a situation to not get items on a 
put.
+                    if ( aux.getCacheType() == CacheType.DISK_CACHE )
+                    {
+                        int numToFree = memCache.getSize();
+                        memCache.freeElements( numToFree );
 
-                // IT USED TO BE THE CASE THAT (If the auxiliary is not a 
lateral, or the cache
-                // attributes
-                // have 'getUseLateral' set, all the elements currently in
-                // memory are written to the lateral before disposing)
-                // I changed this. It was excessive. Only the disk cache needs 
the items, since only
-                // the disk cache
-                // is in a situation to not get items on a put.
+                        if ( log.isInfoEnabled() )
+                        {
+                            log.info( "In DISPOSE, [" + 
this.cacheAttr.getCacheName() + "] put " + numToFree + " into auxiliary " + 
aux.getCacheName() );
+                        }
+                    }
 
-                if ( aux.getCacheType() == CacheType.DISK_CACHE )
+                    // Dispose of the auxiliary
+                    aux.dispose();
+                }
+                catch ( IOException ex )
                 {
-                    int numToFree = memCache.getSize();
-                    memCache.freeElements( numToFree );
-
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( "In DISPOSE, [" + 
this.cacheAttr.getCacheName() + "] put " + numToFree + " into auxiliary " + 
aux.getCacheName() );
-                    }
+                    log.error( "Failure disposing of aux.", ex );
                 }
+            }
 
-                // Dispose of the auxiliary
-                aux.dispose();
+            if ( log.isInfoEnabled() )
+            {
+                log.info( "In DISPOSE, [" + this.cacheAttr.getCacheName() + "] 
disposing of memory cache." );
+            }
+            try
+            {
+                memCache.dispose();
             }
             catch ( IOException ex )
             {
-                log.error( "Failure disposing of aux.", ex );
+                log.error( "Failure disposing of memCache", ex );
             }
         }
-
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "In DISPOSE, [" + this.cacheAttr.getCacheName() + "] 
disposing of memory cache." );
-        }
-        try
-        {
-            memCache.dispose();
-        }
-        catch ( IOException ex )
-        {
-            log.error( "Failure disposing of memCache", ex );
-        }
     }
 
     /**
@@ -1383,20 +1377,17 @@ public class CompositeCache<K, V>
      */
     public void save()
     {
-        synchronized ( this )
+        if ( alive.compareAndSet(true, false) == false )
         {
-            if ( !alive )
-            {
-                return;
-            }
-            alive = false;
+            return;
+        }
 
-            for ( int i = 0; i < auxCaches.length; i++ )
+        synchronized ( this )
+        {
+            for ( ICache<K, V> aux : auxCaches )
             {
                 try
                 {
-                    ICache<K, V> aux = auxCaches[i];
-
                     if ( aux.getStatus() == CacheStatus.ALIVE )
                     {
                         for (K key : memCache.getKeySet())
@@ -1451,9 +1442,9 @@ public class CompositeCache<K, V>
      * @return The status value
      */
     @Override
-    public synchronized CacheStatus getStatus()
+    public CacheStatus getStatus()
     {
-        return alive ? CacheStatus.ALIVE : CacheStatus.DISPOSED;
+        return alive.get() ? CacheStatus.ALIVE : CacheStatus.DISPOSED;
     }
 
     /**
@@ -1749,7 +1740,7 @@ public class CompositeCache<K, V>
      */
     public int getHitCountRam()
     {
-        return hitCountRam;
+        return hitCountRam.get();
     }
 
     /**
@@ -1758,7 +1749,7 @@ public class CompositeCache<K, V>
      */
     public int getHitCountAux()
     {
-        return hitCountAux;
+        return hitCountAux.get();
     }
 
     /**
@@ -1767,7 +1758,7 @@ public class CompositeCache<K, V>
      */
     public int getMissCountNotFound()
     {
-        return missCountNotFound;
+        return missCountNotFound.get();
     }
 
     /**
@@ -1776,7 +1767,15 @@ public class CompositeCache<K, V>
      */
     public int getMissCountExpired()
     {
-        return missCountExpired;
+        return missCountExpired.get();
+    }
+
+    /**
+     * @return Returns the updateCount.
+     */
+    public int getUpdateCount()
+    {
+        return updateCount.get();
     }
 
     /**
@@ -1804,38 +1803,6 @@ public class CompositeCache<K, V>
     }
 
     /**
-     * @param updateCount The updateCount to set.
-     */
-    public synchronized void setUpdateCount( int updateCount )
-    {
-        this.updateCount = updateCount;
-    }
-
-    /**
-     * @return Returns the updateCount.
-     */
-    public synchronized int getUpdateCount()
-    {
-        return updateCount;
-    }
-
-    /**
-     * @param removeCount The removeCount to set.
-     */
-    public synchronized void setRemoveCount( int removeCount )
-    {
-        this.removeCount = removeCount;
-    }
-
-    /**
-     * @return Returns the removeCount.
-     */
-    public synchronized int getRemoveCount()
-    {
-        return removeCount;
-    }
-
-    /**
      * This returns the stats.
      * <p>
      * @return getStats()


Reply via email to