talkingCode

Archive for the concurrency category

Un-overriding hashCode in Java

Problem: you are inheriting from a class in Java. This class has overridden Object.hashCode(). However, you do not want the behaviour of the overriding method, but rather that of the original implementation in the Object class.

Solution: in your new class, create a private field of type Object. Override the hashCode() method in the class to call hashCode() on that field. The result should follow a pattern similar to that below:

public class CustomHashSet<T> extends HashSet<T> {
    private Object hasher;

    public CustomSpecHashSet() {
        super();
        hasher = new Object();
    }
    @SuppressWarnings("unchecked")
    public synchronized Object clone() {
        CustomHashSet<T> copy = (CustomHashSet<T>)super.clone();
        copy.hasher = new Object();
        return copy;
    }

    public int hashCode() { return hasher.hashCode(); }

    public boolean equals(Object o) { return this == o; }
}

Discussion

In Java, once a method has been overridden, it is impossible to get at the original implementation from any inheriting classes. I recently had to deal with this when I wanted to keep some objects that inherited from various Collections inside HashSets, and wanted distinct objects in the set to not be treated as equals just because they happened to contain the same elements. In other words, I needed to use the Object implementations of the hashCode() and equals() methods, rather than the versions defined by the Collections. This is because Object.hashCode() returns a unique integer for every distinct object (typically by using the memory address of an object).

At first, I thought this problem could be solved with reflection. The soloution should simply involve getting a Method instance for Object.hashCode(), and invoke that on any object. Unfortunately, that does not work; calling a method using reflection in Java results in a dynamic method lookup based on the object the method is being invoked on.

Since Java does not permit un-overriding methods, one has to cheat. An object that is never leaked to the outside world can be used to provide a unique integer for each instance. However, care must be taken when implementing classes that support cloning (i.e. implement the Cloneable interface, or inherit from a class that does). Since the clone() method only does a shallow copy of an object, it is essential to override clone(), and make sure that any copies created there get their own instance of the hashing object. There is another gotcha; in the presense of multiple threads accessing the same object, the following clone() implementation would be unsafe:

public Object clone() {
    MyObject copy = (MyObject)super.clone();
    copy.hasher = new Object();
    return copy;
}

This is because the Java memory model only guarantees initialization safety for objects created using a constructor. What this means is that, for an object created using clone() and changing fields after the call to clone(), the updates to those fields are not guaranteed to be seen immediately by other threads accessing that object. A simple way to address this is to put the initialization of the cloned object inside a synchronized block, as in the code given at the top of this recipe.

Haskell, GTK and Multi-Threading

I have been working on an application in Haskell, using Gtk2Hs for the user interface. Now, you normally want a graphical user interface (GUI) to be responsive, so you avoid doing tasks that take a long time in the thread that handles the GUI. Instead, your main computation happens in other application threads, and all that happens in the GUI thread is updating of interface elements. It turns out that there are several issues that come up when you mix Haskell, GTK and multiple threads, which is why this post is here.

Part 1: The GTK event loop

Most programs that use Gtk2Hs first do all the GUI-related initialization, and then execute the mainGUI computation. This is actually a loop that processes GTK-related events until the user quits the program. Because of the way thread switching works in Haskell, a thread executing a loop like that will not let any other “lightweight” threads run. (Lightweight threads are threads created using the forkIO computation.) One frequently suggested way to solve this problem is to make the GTK event loop periodically yield to any other Haskell threads by adding the following to your GUI initialization code:

timeoutAddFull (yield >> return True) priorityDefaultIdle 100

Note that this is only an issue when all lightweight Haskell threads run on top of a single operating system thread, as in the single-threaded RTS of GHC. If Haskell threads are allowed to run on multiple OS threads, then yielding is not necessary.

Part 2: GTK thread safety

It turns out that that GTK (the C library wrapped by Gtk2Hs) is not thread-safe. What this means is that all modifications of GTK state must happen from a single OS thread, which also must be the same thread that is executing the GTK event loop. If all Haskell threads are run on top of a single OS thread, this is easy to ensure. However, if you use a system where lightweight threads may be mapped to different OS threads (such as in the multi-threaded RTS in GHC), care must be taken when accessing a GUI. Essentially, application threads need to put GUI modification events onto a queue, with the thread that runs the GTK event loop processing the events from that queue. Fortunately, Gtk2Hs comes with such a queue built-in; you can use the postGUI functions to give the event loop blocks of IO to execute.

Note that, by default, Gtk2Hs will produce a warning when running under the GHC multi-threaded RTS. To get rid of this, useĀ unsafeInitGUIForThreadedRTS instead of the usual initGUI to perform GTK initialization. The “unsafe” part of the computation name signifies that you are aware of the requirement to only modify GTK state from the correct OS thread.

Part 3: Deconstructing the GTK event loop

There might come a time when you want to do something more complicated than the above solutions allow. In such a case, you can actually substitute the mainGUI event loop with your own. Gtk2Hs provides functions that will process a single event at a time off the GTK event queue. Put these in a loop, sprinkle with your custom logic (such as pulling events off multiple queues), and you’re done!

Context

This was written with the GHC environment in mind. Other Haskell compilers and/or interpreters may differ in their implementations.

Recent Posts
Recent Comments
About Us
jp: works like a charm! thanks!...
Blake: Check this out: http://bugs.adobe.com/jira/browse/SDK-28016...
Boydell: Wow. That was it. You are the only one that had it figured out, and I looked at many...
mark van schaik: thanks! was using a beta SDK version for a production app, which stopped working over...
Sebastian: Steve, I find most asynchronous programming to be incredibly painful. Haskell's appro...

This is the personal blog of a professional software engineer. This site and the views expressed on it are in no way endorsed by the RIAA.