Saturday 18 January 2014

Java result bearing tasks : Callable and Future

Whenever we think of creating threads in Java, Runnable interface comes to mind. If we implement Runnable interface, we need to implement run method which takes no arguments and has no return type. But if we expect a value to be returned after completion of a thread, we need to look for something else. Also Runnable can't throw a checked exception.

That something else is Callable. Callable is an interface introduced in Java 5 to meet this requirement. Callable is similar to Runnable, but it returns a value. The call() method is the entry method into a Callable object and it's return type is the type parameter set in the Callable object. Please note that the call() method in Callable object throws a Checked Exception unlike run() method in Runnable which does not throw any exception.

A Future represents the result of an asynchronous computation. The result can be retrieved using get() method when the computation has completed. The call to get() method blocks until the result is computed. Runnable and Callable represent abstract computational tasks. Future represents the life cycle of a task and provides methods to test whether the task has been completed or been cancelled. It can be used to retrieve the result of a task and also cancel the task. If you want to use Future for the sake of cancellability but not provide a usable result, you declare types of the form Future<?> and return null as the result of the underlying task. FutureTask provides a base implementation of Future. You can refer to online Java documentations to know more about CallableFuture and FutureTask.

I have demonstrated the usage of Callable and Future through the following programs :

RandomStringGenerator class :


RandomStringGeneratorTest class :



Thursday 2 January 2014

LazySet Operations in Java

LazySet is a method offered by Atomic classes in Java. The lazySet method offers significantly cheaper volatile writes for single writers. Let's first find out how lazySet method achieves this performance gain. To find out this, we need to go into the Java Memory Model (JMM). Suppose a primitive variable is shared among different CPU cores. Each core has a local cache where it can store the variable for faster access so that it doesn't have to go to the main memory every time it has to access the variable. If one thread makes a change to this variable, it won't be reflected to the other core since it has a different cache. To mitigate this problem, the Java memory model offers volatile keyword. The reads and writes on a volatile variable would by-pass the cache and go to the main memory. But this comes at a latency cost and lazySet can be used to mitigate this cost. Please note that the cache is not really bypassed, but a memory barrier is used.

The Java Atomic variables have get() and set() methods that work as reads and writes on volatile variables with the additional feature of semi-volatile write. When you change the value of an Atomic variable through the lazySet method, the value is updated in the cache but is not pushed to the main memory. It can take indefinite amount of time of the change to be pushed to the maim memory so that other threads can see the new value. Since in case of lazySet, value is not pushed to the main memory every time, writes are significantly faster. The most important use case lazySet operation is to implement asynchronous logging.