package org.geotools.referencing;
import static org.junit.Assert.*;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.opengis.referencing.crs.CRSAuthorityFactory;
public class CrsCreationDeadlockTest {
private static final int NUMBER_OF_THREADS = 32;
@Test
public void testForDeadlock() throws InterruptedException {
// prepare the loaders
final AtomicInteger ai = new AtomicInteger(NUMBER_OF_THREADS);
final Runnable runnable = new Runnable() {
public void run() {
try {
final CRSAuthorityFactory authorityFactory = ReferencingFactoryFinder
.getCRSAuthorityFactory("EPSG", null);
authorityFactory.createCoordinateReferenceSystem("4326");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
ai.decrementAndGet();
}
}
};
// start them
final List<Thread> threads = new ArrayList<Thread>();
for (int index = 0; index < NUMBER_OF_THREADS; index++) {
final Thread thread = new Thread(runnable);
thread.start();
threads.add(thread);
}
// use jmx to do deadlock detection
try {
final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
while (ai.get() > 0) {
long[] deadlockedThreads = mbean.findMonitorDeadlockedThreads();
if (deadlockedThreads != null && deadlockedThreads.length > 0) {
fail("Deadlock detected between the following threads: "
+ Arrays.toString(deadlockedThreads));
}
// sleep for a bit
Thread.currentThread().sleep(10);
}
} finally {
// kill all the
for (final Thread thread : threads) {
if(thread.isAlive()) {
thread.interrupt();
}
}
}
}
}