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.