Author: curtisr7
Date: Wed Mar 10 15:47:00 2010
New Revision: 921410

URL: http://svn.apache.org/viewvc?rev=921410&view=rev
Log:
OPENJPA-1559: Make DataCacheManager initialization thread safe.

Modified:
    
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java

Modified: 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=921410&r1=921409&r2=921410&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
 Wed Mar 10 15:47:00 2010
@@ -679,13 +679,24 @@ public class OpenJPAConfigurationImpl
         dataCacheManagerPlugin.set(dcm);
     }
 
+    // This boolean is used for double checked locking. We want to minimize 
the amount of time that
+    // we're locking here.
+    private boolean dataCacheManagerInitialized = false;
     public DataCacheManager getDataCacheManagerInstance() {
-        DataCacheManager dcm = (DataCacheManager) dataCacheManagerPlugin.get();
-        if (dcm == null) {
-            dcm =  (DataCacheManager) 
dataCacheManagerPlugin.instantiate(DataCacheManager.class, this);
-            dcm.initialize(this, dataCachePlugin, queryCachePlugin);
+        if (dataCacheManagerInitialized == false) {
+            synchronized (this) {
+                if (dataCacheManagerInitialized == false) {
+                    DataCacheManager dcm = (DataCacheManager) 
dataCacheManagerPlugin.get();
+                    if (dcm == null) {
+                        dcm = (DataCacheManager) 
dataCacheManagerPlugin.instantiate(DataCacheManager.class, this);
+                        dcm.initialize(this, dataCachePlugin, 
queryCachePlugin);
+                    }
+                    dataCacheManagerInitialized = true;
+                    return dcm;
+                }
+            }
         }
-        return dcm;
+        return (DataCacheManager) dataCacheManagerPlugin.get();
     }
 
     public void setDataCache(String dataCache) {

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java?rev=921410&r1=921409&r2=921410&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheScheduler.java
 Wed Mar 10 15:47:00 2010
@@ -18,17 +18,20 @@
  */
 package org.apache.openjpa.persistence.datacache;
 
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.datacache.ConcurrentDataCache;
+import org.apache.openjpa.datacache.DataCacheManager;
 import org.apache.openjpa.datacache.DataCacheScheduler;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.datacache.common.apps.ScheduledEviction;
-import org.apache.openjpa.persistence.test.SingleEMTestCase;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
-public class TestDataCacheScheduler extends SingleEMTestCase {
+public class TestDataCacheScheduler extends SingleEMFTestCase {
 
     private static String getMinutesString() {
         StringBuffer buf = new StringBuffer();
@@ -40,11 +43,16 @@ public class TestDataCacheScheduler exte
     }
 
     public void setUp() {
-        setUp(ScheduledEviction.class, CLEAR_TABLES
+        setUp(
+            "openjpa.DataCache", "true(EvictionSchedule=+1)"
+            , "openjpa.QueryCache", "true"
+            ,"openjpa.RemoteCommitProvider", "sjvm"
+            ,ScheduledEviction.class, CLEAR_TABLES
             );
     }
 
     public void testBasic() throws Exception {
+        OpenJPAEntityManagerSPI em = emf.createEntityManager();
         OpenJPAConfiguration conf = ((OpenJPAEntityManagerSPI) 
em).getConfiguration();
         DataCacheScheduler scheduler = new DataCacheScheduler(conf);
         // Make the scheduler run every 1 minute
@@ -81,6 +89,32 @@ public class TestDataCacheScheduler exte
         assertEquals(3,cache1.getClearCount());
         assertEquals(2,cache2.getClearCount());
     }
+    
+    public void testMultithreadedInitialization() throws Exception {
+        final OpenJPAConfiguration conf =  emf.getConfiguration();
+        final List<DataCacheManager> dcms = new ArrayList<DataCacheManager>();
+        Runnable r = new Runnable(){
+            public void run() {
+                dcms.add(conf.getDataCacheManagerInstance());
+            }
+        };
+        List<Thread> workers = new ArrayList<Thread>();
+        for(int i = 0;i<20;i++){
+            workers.add(new Thread(r));
+        }
+        for(Thread t : workers){
+            t.start();
+        }
+        for(Thread t : workers){
+            t.join();
+        }
+        DataCacheManager prev = dcms.get(0);
+        for(DataCacheManager dcm : dcms){
+            assertTrue(prev == dcm);
+            prev = dcm;
+        }
+
+    }
 
     /**
      * Pass in 4 out of 5 tokens.


Reply via email to