Java coding question and answer on multi-threading
Core Java Coding Questions and Answers for beginner to intermediate level
Q1 | Q2 | Q3 | Q4 | Q5 | Q6 |
Q. Can you review the given code and provide your feedback?
import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); public String formatDate(Date input) { return sdf.format(input); } }A.
1. The code does not fail fast by checking for the preconditions.
2. The above code is not thread-safe as the SimpleDateFormat class is not thread-safe. If you check the API documentation, you will see
Synchronization: Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Here is the illustration of the thread-safety issue with instance variables and the objects they point to having methods not being synchronized.
As you could see, multiple threads are accessing the single instance of the "SimpleDateFormat" object via the reference "sdf". Since the methods in the SimpleDateFormat class are not properly synchronized, they are not thread-safe.
The thread-safety issue can be resolved a number of ways.
Solution 1: Here is the thread safe code.
import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { private static final String SIMPLE_FORMAT = "dd/MM/yyyy"; public String formatDate(Date input) { if(input == null){ return null; } SimpleDateFormat sdf = new SimpleDateFormat(SIMPLE_FORMAT);//local variable return sdf.format(input); } }
Here is the illustration of solution 1.
As you could see, the local variables are thread-safe as each stack will have its own "sdf" reference. The objects are always created in the heap.
Solution 2: While the solution 1 is thread-safe, it will end up creating too many SimpleDateFormat objects in the heap if a single thread invokes the formatDate(Date input) method multiple times. This can be overcome by creating the SimpleDateFormat objects as "per thread singleton" with the ThreadLocal class.
import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { // anonymous inner class. Each thread will have its own copy of the SimpleDateFormat private final static ThreadLocal<simpledateformat> tl = new ThreadLocal<simpledateformat>() { protected SimpleDateFormat initialValue() { return new SimpleDateFormat("dd/MM/yyyy"); } }; public String formatDate(Date input) { if (input == null) { return null; } return tl.get().format(input); } }
Learn more: Java multi-threading interview questions and answers: atomic operations
Solution 3: If "SimpleDateFormat" were your own class, you could have appropriately made it thread-safe , for instance by applying method level or block level synchronization. Since, it is a third party library, you could use a decorator design pattern to wrap the SimpleDateFormat in a new class say SimpleDateFormatWrapper. The SimpleDateFormatWrapper will be made thread-safe.
Can someone write the code for the Solution 3?
Labels: Core Java, Multi-threading
4 Comments:
Thank you for your wonderful work.
Here is my attempt at solution 3:
public class ThreadSafeSimpleDateFormat extends DateFormat
{
private static final long serialVersionUID = 1L;
private static ThreadLocal tl =
new ThreadLocal()
{
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("MM/dd/yyyy");
}
};
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo,
FieldPosition fieldPosition)
{
return tl.get().format(date, toAppendTo, fieldPosition);
}
@Override
public Date parse(String source, ParsePosition pos)
{
return tl.get().parse(source, pos);
}
}
thank u for giving nice explanation..
i have few doubts on solution 2....
why do we need to use static variable for simpledateformat, why don't we use a class variable instead.
and here is my ans about solution 3
it just same as solution 1,
only change is that, instead of using SimpleDateFormat class, we have to write one new class by extending the simpledateformat class as follows
Class ThreadSafeSimpleDateFormat extends SimpleDateFormat
{
public synchronized String format(Date x)
{
return super.format(x);
}
}
is this correct?
Prefer composition to inheritance. I suggest using a local SimpleDateFormat variable in your decorator instead of extending from it.
Yes. Favor composition.
Post a Comment
Subscribe to Post Comments [Atom]
<< Home