× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



I downloaded the source for this and looked at it. I believe that on a
weakly
consistent hardware platform, using the fast path may open you up to
possible
problems.

NOTE: I don't believe there is a problem that I can identify in this code
today
because you're all probably running on strongly consistent hardware.
i.e. Below, where the code in the put() method FIRST stores the object,
THEN stores the
map variable. When thread 2 loads the map variable, you can be sure that
the variables modified previous to the map variable were stored.

Eventually, you'll be on weakly consistent hardware (not just iSeries, but
other platforms too), and in my mind, its better to do it right and not
focus on
which hardware platform you're on.

So... What sort of problems?
I can come up with a few.

Lets look at only two methods of this guy (source excerpted below
for containsValue() and put()), and assume there are many reader threads
(using containsValue() and one writer thread (using put()).

FastHashMap m = new FastHashMap();
Prime with some entries, not including "Threads".

Thread 1:
while (!m.containsValue("Threads")) {
   // No-op
}
// Continue

Thread 2:
// Unrelated work for a while
m.put("Threads");
// Continue unrelated work

Some possible outcomes:
1) After Thread 2 inserts "Threads" into the HashMap, Thread 1 continues to
spin,
'for a while' using the old version of m.map, because although Thread 2
used
'synchronized', thread 1 did not. i.e. thread 1 doesn't ensure that it will
load
the new m.map variable from storage.

2) After Thread 2 inserts "Threads" into the HashMap, Thread 1 sees the
update of
m.map variable right away (by chance, not due to using a synchronized
keyword
to ensure a reload of the variable). Thread 1 then using the get() method
on it,
still doesn't see the updates to HashMap.count nor HashMap.table, so it
doesn't retrieve the value (gets null).

3) Alternative to #2 is that some combination of values of HashMap instance
variables or HashMap.table (Entry object variables) are not flushed, and
this causes some 'worse' form of error, like a NullPointerException.
>From the code in Hashmap.get() this looks unlikely, but the combinations
of what could be theoretically stored is pretty complex, so I wouldn't rule
it out.

So, it may just be that the old version of the map is used and the objects
inserted
are not seen (as it looks like was intended) by the reader thread right
away.
But, it could also easily be that the new version of the map IS used before
the
object insertion is completely flushed to storage. Looking through the code
for
Hashmap, it looks like this will STILL be ok, resulting in a worst case of
simply
a return of null (object not found).
However, the complexity of which instance variables were flushed from
HashMap
and in the Entry objects and which variables were not is pretty large.
So, its hard to be sure.
That's why synchronization is better/safer and easier than trying to
micro-analyze most of the time.



public class FastHashMap extends HashMap {
    protected HashMap map = null;
    protected boolean fast = false;

    public Object put(Object key, Object value) {
        if (fast) {
            synchronized (this) {
                HashMap temp = (HashMap) map.clone();
                Object result = temp.put(key, value);
                map = temp;
                return (result);
            }
        } else {
            synchronized (map) {
                return (map.put(key, value));
            }
        }
    }
    public boolean containsValue(Object value) {

        if (fast) {
            return (map.containsValue(value));
        } else {
            synchronized (map) {
                return (map.containsValue(value));
            }
        }

    }

}

public class HashMap extends blah blah {
   // Instance variables of interest to this guy...
   private transient Entry table[];
   private transient int count;
   public Object put(Object key, Object value) {
      // PUT IS PRETTY BIG. I'VE EXCERPTED HERE
      ....
      // Makes sure the key is not already in the HashMap.
      Entry tab[] = table;
      int hash = 0;
      int index = 0;
      ....
      // Creates the new entry.
      Entry e = new Entry(hash, key, value, tab[index]);
      tab[index] = e;
      count++;
      return null;
   }
   public boolean containsValue(Object value) {
      Entry tab[] = table;

      if (value==null) {
         for (int i = tab.length ; i-- > 0 ;)
            for (Entry e = tab[i] ; e != null ; e = e.next)
               if (e.value==null)
                  return true;
      }
      else {
         for (int i = tab.length ; i-- > 0 ;)
            for (Entry e = tab[i] ; e != null ; e = e.next)
               if (value.equals(e.value))
                  return true;
      }

      return false;
   }
}




"The stuff we call "software" is not like anything that human society
  is used to thinking about. Software is something like a machine, and
  something like mathematics, and something like language, and
  something like thought, and art, and information...
  but software is not in fact any of those other things."
Bruce Sterling - The Hacker Crackdown

Fred A. Kulack - IBM eServer iSeries - Enterprise Application Solutions
ERP, Java DB2 access, Jdbc, JTA, etc...
IBM in Rochester, MN  (Phone: 507.253.5982   T/L 553-5982)
mailto:kulack@us.ibm.com   Personal: mailto:kulack@magnaspeed.net
AIM Home:FKulack  AIM Work:FKulackWrk
MSN Work: fakulack@hotmail.com



                      "David Morris"
                      <David.Morris@plu        To:       
<java400-l@midrange.com>
                      mcreek.com>              cc:
                      Sent by:                 Subject:  RE: FW: Java Vs RPG on 
iSeries
                      java400-l-admin@m
                      idrange.com


                      09/20/2002 03:15
                      PM
                      Please respond to
                      java400-l





I'm always scared that there is a better way or that some gremlin that
will take 50 hours to debug is hiding in my code.  I read the reference

you posted and am wondering how safe the following class is. I have
used this quite a bit particularly for cache type implementations:

http://jakarta.apache.org/commons/collections/api/org/apache/commons/collections/FastHashMap.html


I have never run into any synchronization problems with this class or
some of its related classes, but it now seems it could be dangerous to

switch between the fast and slow modes, which occurs on a cache miss.

David Morris


>>> kulack@us.ibm.com 09/20/02 11:33AM >>>

One of my co-workers said I was scaring people... So I'm probably done
now.
8-)
Sorry about that.

Don't be scared, just be cautious, threads programming is a little
more difficult (even in Java) than many people who love Java would have
you
believe. Just remember to use synchronized {} when sharing data...
_______________________________________________
This is the Java Programming on and around the iSeries / AS400 (JAVA400-L)
mailing list
To post a message email: JAVA400-L@midrange.com
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/cgi-bin/listinfo/java400-l
or email: JAVA400-L-request@midrange.com
Before posting, please take a moment to review the archives
at http://archive.midrange.com/java400-l.










As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.