JSF custom Converter for Date - Is is thread safe?
I have created a custom Converter
in JSF 1.2 to convert Date
objects. The dates have a very particular format. I have implemented my converter using the core Java SimpleDateFormat
class to do the conversion, using the formatter string shown in my code comments below. This all works fine.
My question is about thread safety. The SimpleDateFormat
API docs state that it is not thread safe. For that reason I have created a separate instance of the date format object for each instance of my converter object. However, I'm not sure if this is enough. My DateFormat
object is stored as a member of the DTGDateConverter
.
QUESTION: Will two threads every simultaneously access the same instance of a Converter object in JSF?
If the answer is yes, then my Converter is probably at risk.
/**
* <p>JSF Converter used to convert from java.util.Date to a string.
* The SimpleDateFormat format used is: ddHHmm'Z'MMMyy.</p>
*
* <p>Example: October 31st 2010 at 23:59 formats to 312359ZOCT10</p>
*
* @author JTOUGH
*/
public class DTGDateConverter implements Converter {
private static final Logger logger =
LoggerFactory.getLogger(DTGDateConverter.class);
private static final String EMPTY_STRING = "";
private static final DateFormat DTG_DATE_FORMAT =
MyFormatterUtilities.createDTGInstance();
// The 'format' family of core Java classes are NOT thread-safe.
// Each instance of this class needs its own DateFormat object or
// runs the risk of two request threads accessing it at the same time.
private final DateFormat df = (DateFormat)DTG_DATE_FORMAT.clone();
@Override
public Object getAsObject(
FacesContext context,
UIComponent component,
String stringValue)
throws ConverterException {
Date date = null;
// Prevent ParseException when an empty form field is submitted
// for conversion
if (stringValue == null || stringValue.equals(EMPTY_STRING)) {
date = null;
} else {
try {
date = df.parse(stringValue);
} catch (ParseException e) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to convert string to Date object", e);
}
date = null;
开发者_如何学Go }
}
return date;
}
@Override
public String getAsString(
FacesContext context,
UIComponent component,
Object objectValue)
throws ConverterException {
if (objectValue == null) {
return null;
} else if (!(objectValue instanceof Date)) {
throw new IllegalArgumentException(
"objectValue is not a Date object");
} else {
// Use 'toUpperCase()' to fix mixed case string returned
// from 'MMM' portion of date format
return df.format(objectValue).toUpperCase();
}
}
}
Will two threads every simultaneously access the same instance of a Converter object in JSF?
Depends on how you use the converter. If you use
<h:inputWhatever>
<f:converter converterId="converterId" />
</h:inputWhatever>
then a new instance will be created for every input element in view, which is threadsafe (expect of the very rare edge case that the enduser has two identical views in two browser tabs in the same session and simultaneously issues a postback on the both views).
If you however use
<h:inputWhatever converter="#{applicationBean.converter}" />
then the same instance will be shared across all views of the entire application, which is thus not threadsafe.
You're however cloning a static DataFormat
instance everytime you create the converter. That part is already not threadsafe. You may risk that you're cloning an instance while its internal state is been changed because it's been used somewhere else. Also, cloning an existing instance isn't necessarily cheaper than creating a new instance.
I would recommend to just declare it threadlocal (i.e. inside the method block), regardless of how you use the converter. If the expensiveness of creating the DateFormat
everytime is a major concern (did you profile it?), then consider replacing it by JodaTime.
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.
Yes it is not thread safe here.
Put it local to method and create instance per thread
精彩评论