8/09/2011

Singleton, DCL, Holder Idiom, and When Singleton is not a Singleton

For eager-initialization singleton, the simplest way is to use an enum type with only 1 INSTANCE.  The limitation is your enum singleton class cannot extend from a super class.

public enum EnumSingleton implements Calc {
    INSTANCE;

    public int add(int a, int b) {
        return a + b;
    }
}
A traditional, non-enum implementation of eager-initialization singleton is:
public class EagerSingleton {
    private static EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {}

    public static EagerSingleton getInstance() { return instance; }
} 
A lazy-initialization singleton implemented with double-checked locking (DCL), which works in Java 5 onward:
package test.concurrent;
public final class MySingleton1 {
 private static volatile MySingleton1 instance;

 private MySingleton1() {}

 public static MySingleton1 getInstance() {
   MySingleton1 result = instance;
   if(result == null) {
     synchronized (MySingleton1.class) {
       result = instance;
       if(result == null) {
         instance = result = new MySingleton1();
       }
     }
   }
   return result;
 }
A lazy-initialization singleton implemented with holder idoim (applicable to lazy static field).  The limitation is the instance can only be created with default constructor, and there is no way to pass params from getInstance(...) to the constructor.  In that case, use DCL instead:
package test.concurrent;
public final class MySingleton2 {
 private MySingleton2() {}

 private static class Holder {
   private static final MySingleton2 instance = new MySingleton2();
 }

 public static MySingleton2 getInstance() {
   return Holder.instance;
 }
A main method that spawns multiple threads calling getInstance():
public static void main(String[] args) {
   int numOfThreads = Integer.parseInt(args[0]);
   for(int i = 0; i < numOfThreads; i++) {
     Thread t = new Thread(new Runnable() {
       public void run() {
         System.out.println(MySingleton1.getInstance());
       }
     });
     t.start();
   }
 }
When the same singleton class is loaded by different class loaders, each loader has its own class data. MySingleton1.class loaded by classloader1 is a distinct class from MySingleton1.class loaded by classloader2. Hence multiple instances will be created when calling MySingleton1.getInstance().

To test this scenario, write a servlet that calls MySingleton1.getInstance, and print it. Package the servlet class and MySingleton1 class in test.war, deploy it to appserver. Redeploy the same war in a different context root test2. Invoke the 2 webapp to see if the same instance is printed.

The servlet class:
package test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

@javax.servlet.annotation.WebServlet(urlPatterns = "/*")
public class TestServlet extends HttpServlet {
 protected void processRequest(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
   PrintWriter out = response.getWriter();
   out.println("singleton: " + MySingleton1.getInstance());
 }
 @Override
 protected void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
   processRequest(request, response);
 }
 @Override
 protected void doPost(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
   processRequest(request, response);
 }
}
The content of test.war:
WEB-INF/classes/test/MySingleton1$1.class
WEB-INF/classes/test/MySingleton1.class
WEB-INF/classes/test/TestServlet.class
To deploy the webapp to GlassFish:
$ asadmin deploy test.war
$ asadmin deploy --name test2 test.war
$ asadmin list-applications
To run the 2 webapp and notice 2 different instances of MySingleton class are instantiated within the same JVM, one for each webapp:
$ curl http://localhost:8080/test/
singleton: test.MySingleton1@114536a5

$ curl http://localhost:8080/test/
singleton: test.MySingleton1@114536a5

$ curl http://localhost:8080/test2/
singleton: test.MySingleton1@3997ebf6

$ curl http://localhost:8080/test2/
singleton: test.MySingleton1@3997ebf6

8/08/2011

Join threads with FutureTask and Callable

Here is another way of having the main thread wait for all child threads to complete, using java.util.concurrent.FutureTask and Callable.

package test.concurrent;  
import java.util.Vector;
import java.util.concurrent.*;

public class FutureTaskTest {
private Vector<String> threadNames = new Vector<String>();
public static void main(String[] args) {
FutureTaskTest test = new FutureTaskTest();
test.threadTest(Integer.parseInt(args[0]));
System.out.println(test.threadNames);
}

private void threadTest(int numOfThreads) {
Thread[] threads = new Thread[numOfThreads];
FutureTask<String>[] futureTasks = new FutureTask[numOfThreads];
for (int i = 0; i < threads.length; i++) {
futureTasks[i] = new FutureTask<String>(new MyCallable());
threads[i] = new Thread(futureTasks[i]);
threads[i].start();
}
for (FutureTask<String> f : futureTasks) {
try {
threadNames.add(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

private static class MyCallable implements Callable<String> {
public String call() {
for (int i = 0; i < 1000000; i++) {
i = i + 0;
}
return Thread.currentThread().getName();
}
}
}
FutureTask is usually used along with ExecutorService, but it can also be passed to Thread constructor. The output is always in the order from thread-0 to thread-9, because when we iterate through futureTasks to get result, each get() call wait for a certain duration for the result to be published by child thread.
$ java test.concurrent.FutureTaskTest 10
[Thread-0, Thread-1, Thread-2, Thread-3, Thread-4, Thread-5, Thread-6, Thread-7, Thread-8, Thread-9]
The Vector field threadNames can also be replaced with ArrayList, since it is only accessed in the main thread and no synchronization is needed.

8/07/2011

When to join threads with CountDownLatch

In my previous post When to join threads, Thread.join() is used to wait for all child threads to complete. Now I will update it using CountDownLatch instead:

package test.concurrent;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class ThreadTest {
private Vector<String> threadNames = new Vector<String>();
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.threadTest(Integer.parseInt(args[0]));
System.out.println(test.threadNames);
}

private void threadTest(int numOfThreads) {
final CountDownLatch latch = new CountDownLatch(numOfThreads);
Thread[] threads = new Thread[numOfThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new ThreadTest.MyThread(latch);
threads[i].start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private class MyThread extends Thread {
private final CountDownLatch latch;
public MyThread(CountDownLatch latch) {
this.latch = latch;
}

@Override public void run() {
for (int i = 0; i < 1000000; i++) {
i = i + 0;
}
threadNames.add(getName());
latch.countDown();
}
}
}
A CountDownLatch is created in main thread, passed to each child thread's constructor. Each child thread will count down by 1. After starting all child threads, the main thread then wait for the latch count to reach 0. To run it:
$ java test.concurrent.ThreadTest 10
[Thread-1, Thread-2, Thread-0, Thread-3, Thread-4, Thread-5, Thread-6, Thread-7, Thread-8, Thread-9]

My notes on java thread

(1) Thread.dumpStack(), not Thread.dumpStackTrace(), not Thread.currentThread().dumpStack().

(2) thread can sleep with or without acquiring a lock, inside or outside synchronized block. When sleeping without a lock, the CPU resource is re-allocated to one of the ready-to-run threads. When sleeping inside synchronized block with a monitor lock, the lock is not relinquished, and the CPU is re-allocated to one of the other runnable threads that are not waiting on this lock.

(3) wait-notify-flag pattern. wait is almost always inside a while(flag) loop. There can be multiple threads waiting on the same monitor, some is waiting for the flag to change value, and others are not. In other words, there could be homogeneous threads and/or heterogeneous waiters. Once the flag changes value and notifyAll() is invoked, all threads waiting on the same monitor will be awaken. All of them exit waiting state and enter ready-to-run state, but only one of them will get the lock and proceed. If the lucky one consumes (reset) the flag after obtaining the lock, the previous flag set in notifyAll() becomes obsolete. Therefore, other threads, after they get the monitor, will need to recheck the flag to decide to wait again or proceed.

Another reason wait is inside a loop is there can be spurious wakeup, which are not triggered by notify or notifyAll calls. wait can also be interrupted by other threads. So the wait-notify protocol is not 100% reliable, and that's why a flag is needed to aid the inter-thread communication.

When to use notify and when to use notifyAll? When all waiters are homogeneous, i.e., whoever gets the monitor doesn't matter, use notify. When waiters are heterogeneous, use notifyAll to ensure the correct threads are awaken. If waiter are heterogeneous and we call notify, a waiter that does not care about the flag may be picked to proceed, while those waiters interested in the flag will not get the signal.

The flag should be exclusively for this purpose, not used by other part of the application. All access to this flag is inside synchronized block, so no need to make it volatile or AtomicBoolean.

(4) make the lock object final if possible, for example:

private final Object lock = new Object();
Do not synchronize on string literals, which are merely reference to the same string object in the string pool, or global constants. It will unintentionally cause too many threads competing for the same lock.

(5) volatile can be used on fields of primitive type, primitive wrapper types, or any other Object types. A typical use is in singleton DCL pattern. If a mutable field is simply read or written by multiple threads, then making it volatile usually suffice. One step up in concurrency is to use java.util.concurrent.atomic.* classes like AtomicInteger, AtomicBoolean, etc. Atomic types are ideal for simple compound operations like read-update-assignment, or if-absent-set. Anything more complicated than that will need synchronized access.

Further readings:
Sun's Java Concurrency Tutorial

stackoverflow discussion on wait, notify, CountdownLatch, etc

(6), 3 ways to get a new thread:
* extend java.lang.Thread class and overriding its run() method;

* provide an impl of Runnable interface and use it to instantiate a new thread;

* provide an impl of Runnable interface and call ThreadFactory.newThread(runnable). Get the default ThreadFactory with Executors.defaultThreadFactory().

See their differences in another post: Extend Thread vs implement Runnable

Example of expensive computation

Sometimes I need to simulate some expensive computation, or long-running task, without using Thread.sleep or Object.wait. A real busy waiting. The following example of computing PI is adapted from this RMI tutorial:

package test;
import java.math.BigDecimal;

public class Pi implements java.io.Serializable {
private static final long serialVersionUID = 227L;
private static final BigDecimal FOUR = BigDecimal.valueOf(4);
private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN;
public static void main(String[] args) {
BigDecimal result = computePi(Integer.parseInt(args[0]));
System.out.println("Pi is " + result);
}

/**
* Compute the value of pi to the specified number of digits after the
* decimal point. The value is computed using Machin's formula:
* pi/4 = 4*arctan(1/5) - arctan(1/239)
* and a power series expansion of arctan(x) to sufficient precision.
*/
public static BigDecimal computePi(int digits) {
int scale = digits + 5;
BigDecimal arctan1_5 = arctan(5, scale);
BigDecimal arctan1_239 = arctan(239, scale);
BigDecimal pi = arctan1_5.multiply(FOUR).subtract(arctan1_239).multiply(FOUR);
return pi.setScale(digits, BigDecimal.ROUND_HALF_UP);
}

/**
* Compute the value, in radians, of the arctangent of the inverse of the
* supplied integer to the specified number of digits after the decimal
* point. The value is computed using the power series expansion for the arc
* tangent:
* arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + (x^9)/9 ...
*/
public static BigDecimal arctan(int inverseX, int scale) {
BigDecimal result, numer, term;
BigDecimal invX = BigDecimal.valueOf(inverseX);
BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX);
numer = BigDecimal.ONE.divide(invX, scale, roundingMode);
result = numer;
int i = 1;
do {
numer = numer.divide(invX2, scale, roundingMode);
int denom = 2 * i + 1;
term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode);
if ((i % 2) != 0) {
result = result.subtract(term);
} else {
result = result.add(term);
}
i++;
} while (term.compareTo(BigDecimal.ZERO) != 0);
return result;
}
}
To run and time the task:
$ time java test.Pi 50000
Pi is 3.14159265358979323846264338327950288419716939937510 ...
9.263u 0.187s 0:09.22 102.3% 0+0k 0+6io 8pf+0w
It takes about 10 seconds to compute PI with 5000 digits after the decimal point.

My notes on serialization and de-serialization

I wrote the following test to check some aspects of java serialization and de-serialization, followed by some notes:

package test;
import java.io.*;
import java.util.logging.Logger;

public class SerializableTest implements java.io.Serializable {

private static final long serialVersionUID = 0L;
private static final String fileName = "Serializable.ser";
private static final Logger logger = Logger.getLogger("");
private static String var;
transient private String tran = "this is a transient instance field";
private int number;
private Thread th;

public static void main(String[] args) throws IOException, ClassNotFoundException {
if (args[0].startsWith("ser")) {
SerializableTest test = new SerializableTest();
test.number = 1;
var = "this is a static variable";
writeOut(test);
System.out.println("SerializableTest to be saved: " + test);
} else if (args[0].startsWith("deser")) {
System.out.println("SerializableTest deserialized: " + readIn());
}
}

private static Object readIn() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(fileName)));
return ois.readObject();
}

private static void writeOut(java.io.Serializable obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(fileName)));
oos.writeObject(obj);
oos.close();
}

@Override public String toString() {
return "SerializableTest: final static fileName=" + fileName + ", final static logger=" + logger
+ ", non-final static var=" + var + ", instance number=" + number
+ ", transient instance tran=" + tran + ", non-serializable instance field:=" + th;
}
}
To run the program to serialize an instance to current directory:
$ java test.SerializableTest ser

SerializableTest to be saved: SerializableTest:
final static fileName=Serializable.ser,
final static logger=java.util.logging.LogManager$RootLogger@43ef9157,
non-final static var=this is a static variable,
instance number=1,
transient instance tran=this is a transient instance field
The output dumps the in-memory state of the object, before writing it to disk. To show the file type of the data file containing the object:
$ file Serializable.ser
Serializable.ser: Java serialization data, version 5
To de-serialize, or re-constitute the object from the data file:
$ java test.SerializableTest deser

SerializableTest deserialized:
SerializableTest: final static fileName=Serializable.ser,
final static logger=java.util.logging.LogManager$RootLogger@252f0999,
non-final static var=null,
instance number=1,
transient instance tran=null
The output shows the object state reconstructed from the data file.

(1) transient and static fields are ignored in serialization. After de-serialization transient fields and non-final static fields will be null. Final static fields still have values since they are part of the class data.

(2) ObjectOutputStream.writeObject(obj) and ObjectInputStream.readObject() are used in serialization and de-serialization, not BufferedOutputStream/BufferedInputStream. There is no BufferedObjectOutputStream or BufferedObjectInputStream.

(3) During serialization, you need to handle IOException; during de-serialization, you need to handle IOException and ClassNotFoundException. So the transitive closure of the de-serializaed type must be in the classpath on the receiving side.

(4) Some non-serializable classes: Thread, Logger, LogManager and most classes in java.util.logging (Level and LogRecord are serializable, though). Throwable extends Serializable, so all Error and Exception types are serializable via inheritance.

(5) Uninitialized non-serializable, non-transient instance fields are tolerated. When adding "private Thread th;", no error in serializable. However, "private Thread th = new Thread();" will cause exception:
Exception in thread "main" java.io.NotSerializableException: java.lang.Thread
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at test.SerializableTest.writeOut(SerializableTest.java:33)
at test.SerializableTest.main(SerializableTest.java:19)
(6) It is possible to include static fields in serialization and de-serialization, by implementing writeObject and readObject methods. These 2 methods are not in java.io.Serialiable, which is just a marker interface, and not in java.lang.Object, either. They are just 2 magic methods with pre-defined signatures. The following is from Technical Article: Advanced Serialization
private void writeObject(ObjectOutputStream oos) 
throws IOException {
oos.defaultWriteObject();
// Write/save additional fields
oos.writeObject(new java.util.Date());
}

// assumes "static java.util.Date aDate;" declared
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
ois.defaultReadObject();
// Read/initialize additional fields
aDate = (java.util.Date)ois.readObject();
}
For a definitive guide, refer to Official Java Object Serialization Specification version 6.0

(7) Serialization and de-serialization can be used for copying and cloning objects. It is slower than regular clone, but can produce a deep copy very easily. The following util method is adapted from Secrets of Java Serialization:
    public static Object clone(Object o) 
throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(o);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Object copy = ois.readObject();
ois.close();
return copy;
}

(8) If I need to serialize a Serializable class Person, but one of its superclasses is not Serializable, can Person class still be serializaed and de-serialized? The answer is yes, provided that the non-serializable superclass has a no-arg constructor, which is invoked at de-serialization to initialize that superclass.

(9) How to use a custom class loader during de-serialization? Oftentimes the context class loader of the receiving end is not the right one. Then you will need to create a subclass of java.io.ObjectInputStream, overriding resolveClass method. This is one of the few occasions where you need your own i/o classes.

protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException

(10) Be careful when modifying a class implementing java.io.Serializable. If it does not contain a serialVersionUID field, its serialVersionUID will be automatically generated by the compiler. Different compilers, or different versions of the same compiler, will generate potentially different values. Usually the computation of serialVersionUID is based on not only fields, but also on other aspect of the class like implement clause, constructors, etc. So the best practice is to explicitly declare a serialVersionUID field to maintain backward compatibility. If you need to modify the serializable class substantially and expect it to be incompatible with previous versions, then you need to increment serialVersionUID to avoid mixing different versions.
private static final long serialVersionUID = 42L;
(11) The following is a symptom of a mismatched serialVersionUID:
java.io.IOException: Mismatched serialization UIDs :
The fix is to find out the previous serialVersionUID with $JAVA_HOME/bin/serialver tool, and use it as the value of serialVersionUID field in the new version of the class.

(12) 2 usages of serialization and de-serialization:
  • Temporal serialization: an object is serialized and some time later (could be years later) is restored and put to work.

  • Spatial serialization: an object is serialized and subsequently transferred to another memory space, where it is de-serialized and put to work. This is the more realistic use case than case 1. For example, product foo 1.0 works and exchanges data with product foo 2.0. Or server product A interoperates with server product B through some remoting protocol such as RMI/IIOP. A and B could share some common classes (e.g., javax.ejb.EJBException), and if some common classes do not explicitly declare serialVersionUID, product A and B may compile their own copy and end up having different serialVersionUID.

8/04/2011

Example of Java thread deadlock

A simple example showing a typical Java thread deadlock. 2 threads are spawned: thread-0 first locks lock1 and then lock2; thread-1 first locks lock2 and then lock1. Each thread sleeps a bit before acquiring the second lock, to increase the chance of deadlock.

package test.concurrent;
public class DeadLockTest {
private static long sleepMillis;
private final Object lock1 = new Object();
private final Object lock2 = new Object();

public static void main(String[] args) {
sleepMillis = Long.parseLong(args[0]);
DeadLockTest test = new DeadLockTest();
test.doTest();
}

private void doTest() {
Thread t1 = new Thread(new Runnable() {
public void run() {
lock12();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
lock21();
}
});
t1.start();
t2.start();
}

private void lock12() {
synchronized (lock1) {
sleep();
synchronized (lock2) {
sleep();
}
}
}

private void lock21() {
synchronized (lock2) {
sleep();
synchronized (lock1) {
sleep();
}
}
}

private void sleep() {
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
To run the deadlock test with sleep time 1 millisecond:
java -cp . test.concurrent.DeadLockTest 1
The process seems to hang for ever. To get the thread dump, press Ctrl-\ (Ctrl-break on Windows). Thread dump contains the following deadlock diagnositc:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 1017fcfb0 (object 7f31050b0, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 1017fe360 (object 7f31050c0, a java.lang.Object),
which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
at test.concurrent.DeadLockTest.lock21(DeadLockTest.java:44)
- waiting to lock <7f31050b0> (a java.lang.Object)
- locked <7f31050c0> (a java.lang.Object)
at test.concurrent.DeadLockTest.access$1(DeadLockTest.java:40)
at test.concurrent.DeadLockTest$2.run(DeadLockTest.java:23)
at java.lang.Thread.run(Thread.java:680)
"Thread-0":
at test.concurrent.DeadLockTest.lock12(DeadLockTest.java:35)
- waiting to lock <7f31050c0> (a java.lang.Object)
- locked <7f31050b0> (a java.lang.Object)
at test.concurrent.DeadLockTest.access$0(DeadLockTest.java:31)
at test.concurrent.DeadLockTest$1.run(DeadLockTest.java:18)
at java.lang.Thread.run(Thread.java:680)

Found 1 deadlock.

8/02/2011

Simple Example of JSF and EJB 3.1

This is a very simple example of a JSF 2.0 managed bean invoking EJB 3.1 local singleton EJB. Everything is packaged into a test.war file, and deployed to GlassFish.

test.war consists of 4 entries:

WEB-INF/classes/test/HelloEJB.class
WEB-INF/classes/test/HelloJSFBean.class
WEB-INF/web.xml
index.xhtml
index.xhtml page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<ui:composition>
<h:head>
<h1><h:outputText value="jsf-ejb example" /></h1>
</h:head>

<h:body>
<h:form id="form">
<h:outputLabel value="helloEJB returned message: "/>
<h:outputText value="#{HelloJSFBean.message}"/>
</h:form>
</h:body>
</ui:composition>
</html>
HelloJSFBean managed bean:
package test;
import javax.faces.bean.*;
import javax.ejb.*;

@ManagedBean(name="HelloJSFBean")
@RequestScoped
public class HelloJSFBean implements java.io.Serializable {
@EJB
private HelloEJB helloEJB;

public String getMessage() {
return helloEJB.hello();
}
}
HelloEJB singleton bean:
package test;
import javax.ejb.*;

@Singleton
public class HelloEJB {
public String hello() {
return "Hello from " + this;
}
}
web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
</web-app>
To run the webapp:
curl http://localhost:8080/test/faces/index.xhtml

helloEJB returned message: Hello from test.HelloEJB@1326d2fe

8/01/2011

Runnable, Callable, FutureTask, ExecutorService and thread pool

Some notes on Java concurrency, starting with Runnable vs Callable:

(1), Runnable.run() does not return a value; Callable<T>.run() returns a value of type T. Callable<T> is a parameterized type whose type parameter indicates the return type of its run method. Runnable cannot be parameterized.

(2), Runnable.run() cannot throw any checked exception; Callable<T>.run() can throw checked and unchecked exceptions.

(3), so it seems Callable is more powerful than Runnable. But you cannot just replace all use of Runnable with Callable. For example, in new Thread(runnable). You cannot instantiate a new thread with Callable.

(4), Callable is introduced in Java SE 5, as part of java.util.concurrent library. Callable is mainly intended to use with ExecutorService, which is a higher level service than the direct manipulation of Thread. Both Runnable and Callable can be submitted to ExecutorService for (usually asynchronous) execution.

(5), java.util.concurrent.Executors (a util class similar to Collections, Arrays) has methods to upgrade a Runnable to Callable, but not the other way.

Callable<Object> callable(Runnable task)
<T> Callable<T> callable(Runnable task, T result)
The Callable converted from callable(Runnable) returns null. The Callable converted from callable(Runnable, T) returns T. However, this return value that was passed in by the client is not the real result of executing task. Its purpose is to tell the client that the return type will be Future<T>. In order to obtain the real result, the client still needs to arrange for a thread-safe shared data storage, e.g., a final or volatile field of Runnable impl. Therefore, the converted Callable is still a Runnalbe in its core.

(6) FutureTask is another artifact involving both Callable and Runnable. FutureTask class implements RunnableFuture interface, which in turn extends both Runnable and Future interfaces. So FutureTask is a Runnable by inheritance, and can be passed to new Thread(futureTask), or ExecutorService.submit(futureTask).

FutureTask has a Callable<V> by composition as FutureTask's constructor takes Callable<V> as a param. FutureTask also has another constructor that takes 2 params (Runnable, V), which are simply converted to Callable via Executors.callable(Runnable, V). In fact, the same pattern is employed in java.util.concurrent wherever a method is overloaded with (Callable) and (Runnable, V).

(7), Runnable and Callable run() method takes no param. Why? For one thing, there is no way to know which types are to be passed in. The best we can do is probably Object[] if we were to add params to it. More importantly, it would export state from the calling thread to the task thread, and entails synchronization between the 2 sides. I guess this is why the plain old Runnable.run() takes no param and returns void. In Java 5 to balance simplicity and usefulness, Callable was added to return a result.

(8), how can a task be performed without any params passed to run()? The typical answer is to pass any required data in when instantiating the Callable or Runnable impl class via its constructor. For example,
public class RunnableImpl implements Runnable {
private final List<String> names;

public RunnableImpl(List<String> names) {
this.names = names;
}

public void run() {...}
}
If RunnableImpl is a static inner class, its run() method can directly reference any static fields in the enclosing class. If RunnableImpl is an instance inner class, its run() method can directly reference any static and instance fields in the enclosing class. If RunnableImpl is an anonymous inner class, its run() method can directly reference any static and instance fields of the enclosing class, and any final local variables in the enclosing method.

(9), you can call Thread.setUncaughtExceptionHandler, or Thread.setDefaultUncaughtExceptionHandler to handle exceptions from Runnable.run(). When using ExecutionService where you have no direct control of threads, you can use a custom ThreadFactory. Executors methods newCachedThreadPool, newFixedThreadPool, newScheduledThreadPool, newSingleThreadExecutor, newSingleThreadScheduledExecutor all take a custom ThreadFactory.

(10), Worker thread in thread pools and regular thread are different. A regular thread dies after its run method terminates and cannot be restarted. A worker thread does not die after the completion of the assigned task; it goes back to the thread pool. The main run method of a work thread is an infinite loop: taking a task from the work queue, and invoke the task's run method to do the task.

(11), ThreadLocal variables should be cleared up by the client once the task is done. Otherwise the left-over reference in worker threads prevent the referenced objects from being garbage-collected. Over time it may cause OutOfMemoryError.

(12), The thread pool default work queue in ExecutionService framework is unbounded. It means once the corePoolSize is reached, all subsequent requests will go into this unbound BlockingQueue, until some busy worker threads complete its task. No new worker threads will be created beyond corePoolSize, and maximumPoolSize is ignored in this case. For more details, see bug 6756747: java.util.concurrent.ThreadPoolExecutor doesn't create new worker when it should.