You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2014/04/15 22:25:30 UTC

svn commit: r1587714 - /uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java

Author: schor
Date: Tue Apr 15 20:25:30 2014
New Revision: 1587714

URL: http://svn.apache.org/r1587714
Log:
[UIMA-1249] [UIMA-1598] fixes supporting multiple initialize calls on multiple threads. Make fields either final or volatile, per JCIP (Java Concurrency in Practice)

Modified:
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java?rev=1587714&r1=1587713&r2=1587714&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/resource/impl/CasManager_impl.java Tue Apr 15 20:25:30 2014
@@ -48,27 +48,37 @@ import org.apache.uima.util.impl.CasPool
 /**
  * Simple CAS Manager Implementation used in the AnalysisEngine framework. Maintains a pool of 1 CAS
  * for each requestor.
+ * 
+ * The ResourceManager points to one instantiation of this class.
+ * 
+ * An instance of this class might be accessed in parallel on different threads.
  */
 public class CasManager_impl implements CasManager {
   private ResourceManager mResourceManager;
 
-  private List<ProcessingResourceMetaData> mMetaDataList = new ArrayList<ProcessingResourceMetaData>();
+  /**
+   * accumulates the metadata needed for shared CASes for this resource manager
+   * Starts out "empty" when this is created; is added to (but never removed)
+   * Duplicates may be in the list.
+   */
+  private final List<ProcessingResourceMetaData> mMetaDataList = Collections.synchronizedList(new ArrayList<ProcessingResourceMetaData>());
 
-  private Map<String, CasPool> mRequestorToCasPoolMap = Collections.synchronizedMap(new HashMap<String, CasPool>());
+  private final Map<String, CasPool> mRequestorToCasPoolMap = Collections.synchronizedMap(new HashMap<String, CasPool>());
 
-  private Map<CAS, CasPool> mCasToCasPoolMap = Collections.synchronizedMap(new HashMap<CAS, CasPool>());
+  private final Map<CAS, CasPool> mCasToCasPoolMap = Collections.synchronizedMap(new HashMap<CAS, CasPool>());
   
-  private Map<CAS, UimaContext> mCasToUimaContextMap = Collections.synchronizedMap(new HashMap<CAS, UimaContext>());
+  private final Map<CAS, UimaContext> mCasToUimaContextMap = Collections.synchronizedMap(new HashMap<CAS, UimaContext>());
 
-  private CasDefinition mCasDefinition = null;
+  private volatile CasDefinition mCasDefinition = null;  // once goes non-null, stays
   
-  private TypeSystem mCurrentTypeSystem = null;
+  private volatile TypeSystem mCurrentTypeSystem = null; // once set, same identical typesystem object used for subseq. CASes
 
-  private Object mMBeanServer;
+  private volatile Object mMBeanServer;
 
-  private String mMBeanNamePrefix;
+  private volatile String mMBeanNamePrefix;
   
-  private List<CasPoolManagementImpl> casPoolMBeans = new ArrayList<CasPoolManagementImpl>();
+  private final List<CasPoolManagementImpl> casPoolMBeans = 
+      Collections.synchronizedList(new ArrayList<CasPoolManagementImpl>());
 
   public CasManager_impl(ResourceManager aResourceManager) {
     mResourceManager = aResourceManager;
@@ -79,10 +89,13 @@ public class CasManager_impl implements 
    * 
    * @see org.apache.uima.resource.CasManager#addMetaData(org.apache.uima.resource.metadata.ProcessingResourceMetaData)
    */
-  public void addMetaData(ProcessingResourceMetaData aMetaData) {
+  public synchronized void addMetaData(ProcessingResourceMetaData aMetaData) {
+    if (mCasDefinition != null) {
+      throw new UIMARuntimeException();  // internal error  UIMA-1249
+    }
     mMetaDataList.add(aMetaData);
-    mCasDefinition = null; // mark this stale
-    mCurrentTypeSystem = null; //this too
+//    mCasDefinition = null; // mark this stale
+//    mCurrentTypeSystem = null; //this too
   }
 
   /*
@@ -90,7 +103,7 @@ public class CasManager_impl implements 
    * 
    * @see org.apache.uima.resource.CasManager#getCasDefinition()
    */
-  public CasDefinition getCasDefinition() throws ResourceInitializationException {
+  public synchronized CasDefinition getCasDefinition() throws ResourceInitializationException {
     if (mCasDefinition == null) {
       mCasDefinition = new CasDefinition(mMetaDataList, mResourceManager);
     }
@@ -190,15 +203,20 @@ public class CasManager_impl implements 
    * @see org.apache.uima.resource.CasManager#createNewCas(java.util.Properties)
    */
   public CAS createNewCas(Properties aPerformanceTuningSettings) throws ResourceInitializationException {
-    CAS cas;
+
     if (mCurrentTypeSystem != null) {
-      cas = CasCreationUtils.createCas(getCasDefinition(), aPerformanceTuningSettings, mCurrentTypeSystem);      
-    } else
-    {
-      cas = CasCreationUtils.createCas(getCasDefinition(), aPerformanceTuningSettings);
-      mCurrentTypeSystem = cas.getTypeSystem();
+      return CasCreationUtils.createCas(getCasDefinition(), aPerformanceTuningSettings, mCurrentTypeSystem);      
+    } else {
+      synchronized(this) {
+        if (mCurrentTypeSystem != null) { // double check idiom
+          return CasCreationUtils.createCas(getCasDefinition(), aPerformanceTuningSettings, mCurrentTypeSystem);      
+        } else {
+          CAS cas = CasCreationUtils.createCas(getCasDefinition(), aPerformanceTuningSettings);
+          mCurrentTypeSystem = cas.getTypeSystem();
+          return cas;
+        }
+      }
     }    
-    return cas;
   }
 
   /**
@@ -292,6 +310,9 @@ public class CasManager_impl implements 
   
   /**
    * Registers an MBean for the given CasPool.
+   * 
+   * Never called unless pool is new
+   * 
    * @param aRequestorContextName context name that identifies this CasPool
    * @param pool the CasPool
    */