|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
Code to reproduce threading bugThis quick and dirty hack demonstrates the threading bug in Namespace.java that I posted earlier today. If I run this several times, it eventually hangs forever.
By adding the synchronized keyword to the Namespace.getNamespace(...) method, the program seems to always work. import org.jdom.Namespace; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class JdomThreadBug { public static void main(String[] args) throws InterruptedException { ExecutorService es = Executors.newCachedThreadPool(); int numThreads = 100; CountDownLatch startLatch = new CountDownLatch(1); for (int i = 0; i < numThreads; i++) { es.submit(new Namespacer(i * 10, i * 10 + 10, startLatch)); } startLatch.countDown(); System.out.println("*** DONE ***"); es.shutdown(); } private static class Namespacer implements Runnable { private final int min; private final int max; private final CountDownLatch startLatch; private Namespacer(int min, int max, CountDownLatch startLatch) { this.min = min; this.max = max; this.startLatch = startLatch; } public void run() { try { startLatch.await(); for (int i = min; i < max; i++) { String prefix = "p" + i; String uri = "u" + i; System.out.println("Getting namespace " + prefix + ":" + uri); Namespace.getNamespace(prefix, uri); System.out.println("Got namespace " + prefix + ":" + uri); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } -- Eric M. Burke http://www.linkedin.com/in/ericburke 314-494-3185 (mobile) 636-272-3298 (home) _______________________________________________ To control your jdom-interest membership: http://www.jdom.org/mailman/options/jdom-interest/youraddr@... |
|
|
Re: Code to reproduce threading bugHi Eric,
Thanks for the bug report and especially the test case. I'm checking in a fix. Here's the diff: 150c143,146 < Namespace preexisting = (Namespace) namespaces.get(lookup); --- > Namespace preexisting; > synchronized (namespaces) { > preexisting = (Namespace) namespaces.get(lookup); > } 192c188,190 < namespaces.put(lookup, ns); --- > synchronized (namespaces) { > namespaces.put(lookup, ns); > } Instead of synchronizing the entire method I'm synchronizing just the get and put calls. That keeps the critical sections as small as possible. With this change your test case now runs to completion every time reliably. I didn't synchronize the two initial hash puts that take place in the static initializer block. I'm wondering if there's any potential scenario where the map could be accessed by another thread at that point. If someone can think of a way, write in. -jh- On Dec 16, 2008, at 2:21 PM, Eric Burke wrote: > This quick and dirty hack demonstrates the threading bug in > Namespace.java that I posted earlier today. If I run this several > times, it eventually hangs forever. > > By adding the synchronized keyword to the > Namespace.getNamespace(...) method, the program seems to always work. > > > > import org.jdom.Namespace; > > import java.util.concurrent.CountDownLatch; > import java.util.concurrent.ExecutorService; > import java.util.concurrent.Executors; > > public class JdomThreadBug { > > public static void main(String[] args) throws > InterruptedException { > ExecutorService es = Executors.newCachedThreadPool(); > > int numThreads = 100; > CountDownLatch startLatch = new CountDownLatch(1); > for (int i = 0; i < numThreads; i++) { > es.submit(new Namespacer(i * 10, i * 10 + 10, > startLatch)); > } > > startLatch.countDown(); > System.out.println("*** DONE ***"); > es.shutdown(); > } > > private static class Namespacer implements Runnable { > private final int min; > private final int max; > private final CountDownLatch startLatch; > > private Namespacer(int min, int max, CountDownLatch > startLatch) { > this.min = min; > this.max = max; > this.startLatch = startLatch; > } > > public void run() { > try { > startLatch.await(); > for (int i = min; i < max; i++) { > String prefix = "p" + i; > String uri = "u" + i; > System.out.println("Getting namespace " + prefix > + ":" + uri); > Namespace.getNamespace(prefix, uri); > System.out.println("Got namespace " + prefix + > ":" + uri); > } > } catch (InterruptedException e) { > Thread.currentThread().interrupt(); > } > } > } > } > > > -- > Eric M. Burke > http://www.linkedin.com/in/ericburke > 314-494-3185 (mobile) > 636-272-3298 (home) > _______________________________________________ > To control your jdom-interest membership: > http://www.jdom.org/mailman/options/jdom-interest/ > youraddr@... _______________________________________________ To control your jdom-interest membership: http://www.jdom.org/mailman/options/jdom-interest/youraddr@... |
| Free embeddable forum powered by Nabble | Forum Help |