请用一个代码示例说明为什么SimpleDateFormat不是线程安全的。这门课的问题是什么? SimpleDateFormat的格式功能有问题吗? 请给出在课堂上演示此错误的代码。
FastDateFormat是线程安全的。为什么? SimpleDateFormat和FastDateFormat的区别是什么?
请用一个代码说明这个问题?
请用一个代码示例说明为什么SimpleDateFormat不是线程安全的。这门课的问题是什么? SimpleDateFormat的格式功能有问题吗? 请给出在课堂上演示此错误的代码。
FastDateFormat是线程安全的。为什么? SimpleDateFormat和FastDateFormat的区别是什么?
请用一个代码说明这个问题?
当前回答
commons-lang的3.2版将拥有FastDateParser类,它是SimpleDateFormat的线程安全替代品。更多信息请参见LANG-909。
其他回答
commons-lang的3.2版将拥有FastDateParser类,它是SimpleDateFormat的线程安全替代品。更多信息请参见LANG-909。
下面是一个代码示例,它证明了类中的错误。我检查过:问题发生在使用解析时,也当你只使用格式。
下面的示例将SimpleDateFormat对象定义为静态字段。当两个或多个线程以不同的日期并发地访问“someMethod”时,它们可能会扰乱彼此的结果。
public class SimpleDateFormatExample {
private static final SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
public String someMethod(Date date) {
return simpleFormat.format(date);
}
}
您可以创建如下所示的服务,并使用jmeter模拟并发用户,使用相同的SimpleDateFormat对象格式化不同的日期,结果将是混乱的。
public class FormattedTimeHandler extends AbstractHandler {
private static final String OUTPUT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
private static final String INPUT_TIME_FORMAT = "yyyy-MM-ddHH:mm:ss";
private static final SimpleDateFormat simpleFormat = new SimpleDateFormat(OUTPUT_TIME_FORMAT);
// apache commons lang3 FastDateFormat is threadsafe
private static final FastDateFormat fastFormat = FastDateFormat.getInstance(OUTPUT_TIME_FORMAT);
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
final String inputTime = request.getParameter("time");
Date date = LocalDateTime.parse(inputTime, DateTimeFormat.forPattern(INPUT_TIME_FORMAT)).toDate();
final String method = request.getParameter("method");
if ("SimpleDateFormat".equalsIgnoreCase(method)) {
// use SimpleDateFormat as a static constant field, not thread safe
response.getWriter().println(simpleFormat.format(date));
} else if ("FastDateFormat".equalsIgnoreCase(method)) {
// use apache commons lang3 FastDateFormat, thread safe
response.getWriter().println(fastFormat.format(date));
} else {
// create new SimpleDateFormat instance when formatting date, thread safe
response.getWriter().println(new SimpleDateFormat(OUTPUT_TIME_FORMAT).format(date));
}
}
public static void main(String[] args) throws Exception {
// embedded jetty configuration, running on port 8090. change it as needed.
Server server = new Server(8090);
server.setHandler(new FormattedTimeHandler());
server.start();
server.join();
}
}
代码和jmeter脚本可以在这里下载。
如果你想在多个线程中使用相同的日期格式,请将其声明为静态格式,并在使用时对实例变量进行同步…
static private SimpleDateFormat sdf = new SimpleDateFormat("....");
synchronized(sdf)
{
// use the instance here to format a date
}
// The above makes it thread safe
Java 8中的DateTimeFormatter是不可变的线程安全的SimpleDateFormat的替代品。