Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


Hash codes

Hash codes are integers used as keys in hash tables. Each object that can serve as a key in a hash table must be associated with a precise integer. The list of items in the hash table is then indexed with these integer keys. Equal objects — objects which compare equal to each other with the equals() method — are supposed to have identical hash codes. Unequal objects normally have different hash codes, although this is not always true. The efficiency of a hash table is closely related to the percentage of objects in the table with unique keys.

The default hashCode() method used by java.lang.Object is the numeric value of the reference to the object. Although Java programs aren’t allowed to convert 32-bit references to 32-bit ints, you can do this in native C code, and that’s exactly what Java does, at least on 32-bit platforms. (Porting Java to 64-bit platforms like the DEC Alpha or 16-bit platforms like Windows 3.1 is decidedly non-trivial, for this and many other similar reasons.)

No reference can point to two different objects. Therefore, hash codes calculated in this fashion will always be unique. Conversely, no object can have two different addresses, so an object always has the same hash code. (An object can be referred to by two different reference variables, but these two variables will still have the same value.)

The hashCode() method is closely tied to the equals() method. When you override equals(), you need to override hashCode(), too. Remember that all objects that are equal according to the equals() method must have the same hash code.

Threading

Discussion among many people in the same place at the same time tends to degenerate rapidly into babble as everyone begins talking at once. To make discussion possible among large groups of people, a special object, sometimes called a “magic feather,” is created and endowed with the special power that only the person holding the magic feather may speak. Because no more than one person can hold the magic feather at a time, no more than one person can talk at one time.

Many different threads talking at the same time can be a huge problem for Java programs as well. It is extremely important to guarantee that two different threads don’t modify the same object at the same time. Therefore, each object is created with its own magic feather. The magic feather for an object can be held by at most one thread at any given time. As long as a thread holds an object’s magic feather, it can do anything it’s normally allowed to do with the object. All other threads that want to use the object have to wait until they get the object’s magic feather.

I should note that “magic feather” isn’t a sufficiently impressive technical term for most programmers. Instead, the commonly used word is monitor.

If you search the java packages, you won’t find any class called monitor or magic feather. A monitor is not a separate object. It is a part of each individual object. Threads ask for an object’s monitor when they execute a synchronized instance method of the object, execute the body of a synchronized statement that synchronizes on the object, or invoke a synchronized static method of a class. (In the latter case, the Class object associated with the class is synchronized.) Threads give back the monitor when they finish executing the synchronized code.

By calling one of an object’s wait() methods, a thread can yield possession of the monitor and put itself to sleep until the monitor is available again. The thread can then be awakened with the object’s notify() or notifyAll() methods. There are three polymorphic wait() methods. These are

     public final void wait() throws InterruptedException
     public final void wait(long  ms) throws InterruptedException
     public final void wait(long  ms, int  ns) throws InterruptedException

Each of these methods causes the calling thread to release the object’s monitor and go to sleep until another thread notifies threads waiting on this object’s monitor to wake up. At that point, the thread wakes up, waits until it can regain the object’s monitor, and then resumes running. The first wait() method, with no arguments, sleeps indefinitely. The second, with a single long argument, sleeps for at most the specified number of milliseconds and then wakes up whether it has been notified or not.

The third and final wait() method allows more finely grained control, down to a nanosecond. The first argument is the number of milliseconds to wait before waking, and the second argument is the number of nanoseconds to add to that. Not all architectures allow such finely grained timing. You shouldn’t rely on accuracy of more than a millsecond or two.

There are two notify methods: notify() and notifyAll(). Their signatures are

     public final void notify()
     public final void notifyAll()

The notify() method wakes up a single thread that’s waiting on this object’s monitor. The notifyAll() method wakes up all threads waiting on this object’s monitor. Both of these methods should be called only in a thread that owns the object’s monitor.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.