Languages‎ > ‎Java‎ > ‎

Is Threaded Java is Too Difficult?

A quick Java quiz: can you find the bug in the following code fragment?

Code

public class DateFormatter {

private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

public static String getDateAsString(Date date) {
return df.format(date);
}
}



Corrected Version:



import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatter {
private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

public synchronized static String getDateAsString(Date date) {
return df.format(date);
}
}


It looks too simple to have a bug, and yet it does. In some tests I performed, the getDateAsString(Date) method returned the wrong value roughly 1 time in 5000 on a machine with a single core CPU. On a dual core machine it gave the wrong value about 100 times in 5000!

The bug is that the DateFormatter class above is not thread safe. Or to be more precise, an instance of java.text.SimpleDateFormat can't be shared reliably among threads. If you use code such as this in a web application as a central place to format dates, you'll occasionally get the wrong value.

Who's to blame? Is it sloppy programming on my behalf? or sloppy programming from whoever wrote the SimpleDateFormat class? or poor documentation of the SimpleDateFormat class (the javadocs do mention this problem, but in a somewhat hard-to-decipher manner, and clearly as an afterthought)? or a flaw in the design of Java that allows such a hard-to-detect bug to be so easily written?

 

Some commentators on the state of programming predict that a time will soon come when all software developers must be competent in concurrency. The line of thinking is that because CPU's have stopped getting faster, and instead offer better performance through 2, 4, or more CPU cores, we'll need to write our software using approaches that use all cores. This means we'll need to use algorithms, patterns, and languages that aid multi-threaded development. However I argue that the time has already come, and has in fact been here for years.

This is because the most common software projects are inherently multi-threaded. I guess the two most common types of Java projects are web applications and Swing-based GUIs, both of which are multi-threaded. Often programmers are not aware that they are exposed to awkward multi-threaded issues, and as a consequence subtle but potentially severe bugs creep into their code. In multi-CPU or multi-core environments, we are simply more likely to be hurt by those subtle concurrency bugs that already existed.



Comments