Java Tips: Thread Safety Documentation

Joshua Bloch in his book, “Effective Java” summarized the levels of thread safety:

  • immutable—Instances of this class appear constant. No external synchronization is necessary. Examples include String, Long, and BigInteger (Item 15).
  • unconditionally thread-safe—Instances of this class are mutable, but the class has sufficient internal synchronization that its instances can be used concurrently without the need for any external synchronization. Examples include Random and ConcurrentHashMap.
  • conditionally thread-safe—Like unconditionally thread-safe, except that some methods require external synchronization for safe concurrent use. Examples include the collections returned by the Collections.synchronized wrappers, whose iterators require external synchronization.
  • not thread-safe—Instances of this class are mutable. To use them concurrently, clients must surround each method invocation (or invocation sequence) with external synchronization of the clients’ choosing. Examples include the general-purpose collection implementations, such as ArrayList and HashMap.
  • thread-hostile—This class is not safe for concurrent use even if all method invocations are surrounded by external synchronization. Thread hostility usually results from modifying static data without synchronization. No one writes a thread-hostile class on purpose; such classes result from the failure to consider concurrency. Luckily, there are very few thread-hostile classes or methods in the Java libraries. The System.runFinalizersOnExit method is thread-hostile and has been deprecated.

Let we find a simplest example of classes for each of the mentioned level.

Immutable

public class ImmutableClass {

    private String a;

    public ImmutableClass(String a) {
        this.a = a;
    }

    public String getA() {
        return a;
    }

}

Unconditionally Thread Safe

public class UnconditionallyThreadSafeClass {

    private String a;

    private Object syncObject = new Object();

    public UnconditionallyThreadSafeClass(String a) {
        this.a = a;
    }

    public void setA(String a) {
        synchronized (syncObject) {
            this.a = a;
        }
    }

    public String getA() {
        synchronized (syncObject) {
            return a;
        }
    }

}

Conditionally Thread Safe

import java.util.ArrayList;

public class ConditionallyThreadSafeClass {

    private ArrayList<String> a;

    private Object syncObject = new Object();

    public ConditionallyThreadSafeClass(ArrayList<String> a) {
        this.a = a;
    }

    public void add(String s) {
        synchronized (syncObject) {
            a.add(s);
        }
    }

    public ArrayList<String> getA() {
        return a;
    }

}

Not Thread Safe

public class NotThreadSafeClass {

    private String a;

    public NotThreadSafeClass(String a) {
        this.a = a;
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }
}

Thread Hostile

public class ThreadHostileClass {

    private static String a;

    public ThreadHostileClass(String a) {
        ThreadHostileClass.a = a;
    }

    public String getA() {
        return a;
    }

    public void doSomethingToA(final String a) {
        new Thread() {
            public void run() {
                ThreadHostileClass.a = a;
            }
        }.run();
    }
}

Java Tips: Memory Optimization for String

String is a unique object in Java. The Java Specification explains several unique properties of String in Java. We might already know some of them. First, String is unique because it can be created without new keyword, like example below.

String s = "new String";

I have to mention that you can still create String object using new keyword, like this:

String s = new String("new String");

Does both statement “exactly equals”? Well, most of you also know that this is not true. The first example will try to reuse the same object whenever possible (and is correct because String is immutable) while the second will force the creation of new String object. Consider this example:

System.out.println("b" == "b");
System.out.println(new String("b") == new String("b"));

The result of first example is “true” while the second one will give “false”.

I almost certain that experienced programmer will never create String using new in normal use. But sometime, we are forced to use that. One case that I can think of is when you parse an XML file using SAX parser.

public class Reader extends DefaultHandler {

    private List<String> listString = new ArrayList<String>();

    public void characters(char[] ch, int start, int length) throws SAXException {

        String content = new String(ch, start, length);
        listString.add(content);

    }
}

This example works correctly but is not efficient. Once you have a document like this:

<test>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
    <string>String</string>
</test>

Try to profile your application, force garbage collection and you will still have ten String objects left in the memory.

Fortunately, Java has provided a method to avoid such case. You can use String.intern() to force the application to use the same String object whenever possible. For above example, you can change the code to something like this:

public class Reader extends DefaultHandler {

    private List<String> listString = new ArrayList<String>();

    public void characters(char[] ch, int start, int length) throws SAXException {

        String content = new String(ch, start, length).intern();
        listString.add(content);

    }
}

Now, re-profile the application, force garbage collection, and you will only have one String left in the memory. You can save a lot of memory if you can make sure that there is only one instance of String with certain value in your JVM.

This method also has nice side effect. If you do a lot of String equality comparison in the application, a same String object run faster. To explain this, we can read the source code of String:

...
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}
...

If the object is same, then the method will be immediately after this line if (this == anObject). This is very fast and will save a lot of process time if your application do this operations a lot of time.

Spring Tips: Initializing bean using EasyMock for unit test

Unit test is a very good practice for creating robust application. Using Spring, we can avoid using ApplicationContext and instead arrange all dependencies programmatically. However, once in a while, we still need to test using the actual ApplicationContext. This can be problematic if our test using mock from EasyMock.

So here is the example on how to create a mock using EasyMock programmatically:

AccountDAO accountDAOMock = EasyMock.createMock(AccountDAO.class);

Move it to Spring ApplicationContext like this:

<bean id="accountDAOMock" class="org.easymock.EasyMock"
		factory-method="createMock">
      <constructor-arg index="0"
            value="com.argus.camc.datamanagement.interfaces.AccountDAO" />
</bean>

Happy unit testing!

My top Eclipse keyboard shortcut

eclipse logo

If you use Eclipse a lot you must have your favorite keyboard shortcut. Here are mine:

  1. Context Assist (CTRL+SPACE), I believe this is all favorite since they just have so many functionality. You want assistance about class name/method name/variable name. You get all. More than that, it also shows the template available for the context. It even suggests the possible variable name/method name. And it works in all places, even in the dialogs. This is a must know keyboard shortcut for all Eclipse user. Without it, you just will not get anything from Eclipse.
  2. Format (Shift+Ctrl+F), I usually type anything as fast as I can without bothering the format of the code. This shortcut will tidy up all the clutter and make my code readable.
  3. Save (Ctrl+S). OK, I know that this is a must for nearly all applications.
  4. Quick Fix (Ctrl+1). You get error or warning? Many times you will find that this shortcut can solve the problem for you.
  5. Rename (Ctrl+2+R). Since I’m a refactoring guy, I never escape from this task, renaming variables/methods/classes.
  6. Quick Type Hierarchy (Ctrl+T). Nice way to get information about classes tree without opening JavaDoc

So if you are also using Eclipse, what’s your favorite keyboard shortcut?

Java Tips: MessageFormat

Writing a working code is not enough. There is so wide spectrum from where we can distinguish good programmer and a bad one. This is one example of it.

Suppose we need to write a String that concatenate several predefined substrings with several variables. What do we do? Obviously, the most natural thing is to write:

String c = "The book with title " + title + " is sold with price "
              + price + " to " + buyername;

Nothing wrong with the code but obviously if the sentence build many times, you already know that it’s not that efficient. The use of StringBuffer or StringBuilder in Java 5 can make it much better.

String c = new StringBuilder("The book with title ").append(title)
                    .append(" is sold with price ").append(price)
                    .append(" to ").append(buyername);

Great! But not for future development. The code looks cryptic and hard to be changed. The use of MessageFormat is the best solution for such problem (which unfortunately, also the most inefficient).

String result = MessageFormat.format(
     "The book with title {0} is sold with price {1} to {2}",
      new Object[] {title, price, buyername});

This is even better since we can customize the format of the price, for example:

String result = MessageFormat.format(
     "The book with title {0} is sold with price {1,number,currency} to {2}",
      new Object[] {title, price, buyername});

Fixing Samba symbolic links' problem from Leopard

Oh no… all symbolic links are not accessible from Leopard. It shows error message that the target links can’t be found. They are OK with Tiger, so I’m thinking that there is a bug in Leopard. For a while, I can live with copying the file from Linux to Mac and worked with the copy in Mac. But when the first update of Leopard is out, it’s still not fixed so I somehow curious what really happen here.

So today I spent some time to examine the problem and found a suggestion from here to restart the samba server everytime mac connects to it. It’s not that convenient.

Reading more to the links given by it, I found out that simpler solution is available. Just by adding this line to smb.conf (in Ubuntu the location is /etc/samba/smb.conf), the problem can be resolved.

unix extensions = no

“Force link that open new window to open in new tab” for Firefox 2

Firefox 2 removes option to “Force link that open new window to open in new tab”. I found this to be very disappointing, since I always activate this option. Working with tabs is one of the reason I use Firefox, if some sites force me to open new window, it is just as annoying as using MSIE 6 again!!

So here is how you can set this in Firefox 2:

Open about:config and set:

browser.link.open_external -&gt; 3
browser.link.open_newwindow -&gt; 3
browser.link.open_newwindow.restriction -&gt; 2

And you’re done!

technology and stuffs