Monthly Archive for January, 2009

Wi-Fi Detector Shirt

Wi-Fi Detector Shirt

Here at ThinkGeek we’re pretty lazy when it comes to technology. We expect our gadgets to do all the busywork while we focus on the high level important tasks like reading blogs. That’s why we hate to have to crack open our laptops just to see if there is any wi-fi internet access about… and keychain wi-fi detectors, we would have to actually remove them from our pockets to look at them. But now thanks to the ingenious ThinkGeek robot monkeys you can display the current wi-fi signal strength to yourself and everyone around you with this stylish Wi-Fi Detector Shirt. The glowing bars on the front of the shirt dynamically change as the surrounding wi-fi signal strength fluctuates. Finally you can get the attention you deserve as others bow to you as their reverential wi-fi god, while geeky chicks swoon at your presence. You can thank us later.

From: http://www.thinkgeek.com/tshirts-apparel/interactive/991e/?selsku=1

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.

Java Tips: More About Initializing Collection

Some time ago I wrote an article about initializing collection in Java. I just found that Java actually provides several methods to help this task if you just want to create empty or singleton collection.

Look at this:

Collections.EMPTY_LIST
Collections.EMPTY_MAP
Collections.EMPTY_SET
Collections.singleton(...)
Collections.singletonList(...)
Collections.singletonMap(..., ...)