[concurrency-interest] ConcurrentHashmap.putIfAbsent oddities

Hanson Char hanson.char at gmail.com
Mon Dec 11 11:39:07 EST 2006


Consider changing "this.urls = urls;" to "this.urls = urls.clone();".  The
reference to the array "urls" is immutable (via final), but the content of
the "urls" array is still mutable and not thread-safe, which will cause
undesirable effect in the context of being used as a key.

Another trick you may consider for finding out the root cause at least is to
do something like below.  The basic idea is to make the hashCode and equals
being predictable/consistent all the time..

Hanson

     private class LoaderKey extends WeakReference {
                private final URL[] urls;
                private final boolean nullParent;
                private final int hashValue;
                private final String urlsString;

                public String toString() {
                      return urlsString;
                }

                public LoaderKey(URL[] urls, ClassLoader parent) {
                        super(parent, refQueue);
                        this.urls = urls.clone();
                        nullParent = (parent == null);
                        String str = "LoaderKey: (parentnull="+nullParent+")
"+Arrays.toString( this.urls );

                        if( logger.isLoggable(Level.FINER) )
                                str += ": loader="+get();
                        urlsString = str;
                        hashValue = urlsString.hashCode();
                        // Log both urlsString and hashValue here for
debugging purposes.
                }

                public int hashCode() {
                        return hashValue;
                }

                public boolean equals(Object obj) {
                        if (obj == this) {
                                return true;
                        } else if (!(obj instanceof LoaderKey)) {
                                return false;
                        }
                        LoaderKey other = (LoaderKey) obj;
                        return this.urlsString.equals(other.urlsString);
                }
     }


On 12/11/06, Gregg Wonderly <gergg at cox.net> wrote:
>
> Hanson Char wrote:
> > Can you provide the implementation of the equals() and hashCode()
> > methods of LoaderKey ?  The usual suspects.
>
>      private class LoaderKey extends WeakReference {
>                 private final URL[] urls;
>                 private final boolean nullParent;
>                 private final int hashValue;
>
>                 public String toString() {
>                         String str = "LoaderKey:
> (parentnull="+nullParent+") "+Arrays.toString( urls );
>                         if( logger.isLoggable(Level.FINER) )
>                                 str += ": loader="+get();
>                         return str;
>                 }
>
>                 public LoaderKey(URL[] urls, ClassLoader parent) {
>                         super(parent, refQueue);
>                         this.urls = urls;
>                         nullParent = (parent == null);
>
>                         int h = nullParent ? 0 : parent.hashCode();
>                         for (int i = 0; i < urls.length; i++) {
>                                 h ^= urls[i].hashCode();
>                         }
>                         hashValue = h;
>                 }
>
>                 public int hashCode() {
>                         return hashValue;
>                 }
>
>                 public boolean equals(Object obj) {
>                         if (obj == this) {
>                                 return true;
>                         } else if (!(obj instanceof LoaderKey)) {
>                                 return false;
>                         }
>                         LoaderKey other = (LoaderKey) obj;
>                         ClassLoader parent = (ClassLoader) get();
>                         return (nullParent ? other.nullParent
>                                  : ( parent != null &&
>                                                 parent == other.get() ) )
>                                                 && Arrays.equals(urls,
> other.urls);
>                 }
>      }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20061211/cb156f0c/attachment-0001.html 


More information about the Concurrency-interest mailing list