Archive for September, 2004

18
Sep
04

String.intern() and synchronization

It’s very common that whenever you need to synchronize on a String value (for example, a username) you must synchronize on a common single object for all the intances of Strings that are Object.equals(Object) among them (you need to synchronize concurrent access to the system for the same user). Also it’s very common to choose this common single object as the value of a Hashtable with the keySet being the String values.

Lets code it:

Map lockMap=new Hashtable();
//…
public boolean createWorkspace(String username) {
   synchronize(getCommon(username)) {
       //your stuff
   }
}
//…
//does not work!
private Object getCommon(String value) {
    Object common=lockMap.get(value);
    if(common==null) {
        common=new Object();
        lockMap.put(value,common);
    }
    return common;
}
 

This won’t work because if two thread with the same username has just one line of difference they could return different “common” objects. The following doesn’t work either for the same reason. Two different threads with the same value can enter into the if.

//doesn’t work either!
private Object getCommon(String value) {
    if(lockMap.get(value)==null) {
        lockMap.put(value,new Object());
    }
    return lockMap.get(value);

}

 

So it seems that the only solution is to synchronize the whole method, whether on the lockMap object or on the instance of our code (suppose it’s a singleton). The code should be something like:

private Object getCommon(String value) {
    synchronized(lockMap) {
        Object common=lockMap.get(value);
        if(common==null) {
            common=new Object();
            lockMap.put(value,common);
        }
        return common;

    }

}
 

And you maybe ask: what’s the problem here? Well, the problem is that in some point of our system we are synchronizing (pausing) all threads when we just wanted to pause the threads that have the same username value. And we are doing this with all the users that want to use the system. So we are in a bottleneck scenario, so the problem here is performance.

So, what to do? Well, for a very unknown reason there is a String method that is almost unknown among all Java developers. This method have been in the String class at least since JDK 1.1 (but I’m almost sure I saw it in the very old 1.0.2, but at the moment of writing this post, this version wasn’t available in the Archive: Java Technology Products Download page) The method documentation says

Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
It follows that for any two strings s and t,
s.intern() == t.intern()
is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the
Java
 Language Specification

Returns:a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

So, we should code as the following:

public boolean createWorkspace(String username) {
   synchronize(username.intern()) {
       //your stuff
   }
}
 

I used this aproximation about three years ago on an entry point of a online e-banking application, and worked quite well. Now, looking in the web about this solution I found that this was the topic of the Question of the week Number 158 of the developers.sun.com  more or less 30 weeks ago.

15
Sep
04

Bonobos

Bonobos in their natural habitat
This article Bonobo Sex and Society, which was originally published by Scientific American is an excellent resource about Bonobos. I’m convinced that every human being should read about these close relatives.
Afterwards, you can read more about bonobos going through the book Bonobo: The Forgotten Ape. Both, the book and article were written by the same author: Frans de Waal.

15
Sep
04

Comparación

Imaginemos a una madre de familia haciendo que diariamente todos sus hijos digan al unísono algo muy agradable a su padre con una invitación del estilo: “Todos digan: te amamos mucho, papá”, justo cuando el papá llega a desayunar. Ahora añadamos a la escena el hecho de que el papá se la cree y de hecho realmente disfruta de que los niños hagan ese esfuerzo, aunque realmente como que los niños no hagan el esfuerzo de aprenderse exactamente las palabras que deben decir en ese momento. Pero eso no importa, el papá se la cree y realmente se siente amado por sus hijos.

Ok, ahora comparemos eso al hecho semanal de un sacerdote que dice en muchos momentos de la Misa: “Respondemos todos: Bendito seas por siempre, Señor”. Imagínense qué clase de deidad debiera ser para creersela y pensar que está cool que todos repitan así la liturgia. Pues esa es la clase de deidad que promueve el catolicismo… o por lo menos un buen número de sacerdotes católico. Sinceramente me pregunto qué crerán los sacerdotes que gana para su dios y su gloria el hecho de que todos repitan después de él la frase correcta. Claramente es un asunto religioso, esto es, la que gana ahí es la religión y con ello el fortalecimiento del vínculo entre la conciencia y los estatutos morales que rigen los valores de esa religión. Pero la pregunta persiste: ¿qué tiene que ver una religión con una deidad? ¿qué podríamos saber de una deidad a través de religiones o ministros de ese calibre?

Sin duda, un asunto penoso. Sobretodo si se reflexiona sobre los elementos tan mezquinos con los que se amarran a las conciencias de los hombres y las mujeres que caen en ese trinomio culpa-arrepentimiento-perdón.

14
Sep
04

Camila (17 months)


Camila, my daughter




Yo mero

My music tag cloud

@justavo