[jdom-interest] Code to reproduce threading bug
Jason Hunter
jhunter at servlets.com
Wed Dec 17 15:21:59 PST 2008
Hi 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 at yourhost.com
More information about the jdom-interest
mailing list