SimpleDateFormat日期转换之线程安全问题解决方案

编程入门 行业动态 更新时间:2024-10-26 01:29:16

SimpleDateFormat日期转换之<a href=https://www.elefans.com/category/jswz/34/1771240.html style=线程安全问题解决方案"/>

SimpleDateFormat日期转换之线程安全问题解决方案

java 日期转换,线程安全问题

java.text.SimpleDateFormat,是线程非安全,原因在于SimpleDateFormat中,使用到了Calendar类对象,在执行parse() 和format()方法时,调用calendar.setTime(date)方法。那么问题来了:多线程环境下,线程非安全。 
解决方案:
1)每次使用,都创建新实例; 
2)使用三方类库。

package com.time;import org.apachemons.lang.time.DateFormatUtils;
import org.apachemons.lang.time.DateUtils;
import org.apachemons.lang.time.FastDateFormat;import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** Created by Liuxd on 2018-08-28.*/
public class TestTime {private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");private static final FastDateFormat timeFormat = FastDateFormat.getInstance("yyyy-MM-dd");private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");public static void TestDateTimeFormatter(ExecutorService pool) {for (int i = 0; i < 100000; i++) {Date date = DateUtils.addDays(new Date(), i);pool.execute(new Thread() {@Overridepublic void run() {String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");LocalDate localDate = LocalDate.parse(dateStr, formatter);String dateAfter = formatter.format(localDate);System.out.println(dateStr + "   " + dateAfter);if (!dateStr.equals(formatter.format(localDate))) {System.out.println(dateStr + "   " + dateAfter + "   发生异常情况");}}});}}public static void TestFastDateFormat(ExecutorService pool) {for (int i = 0; i < 100000; i++) {Date date = DateUtils.addDays(new Date(), i);pool.execute(new Thread() {@Overridepublic void run() {String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");String dateAfter = timeFormat.format(date);System.out.println(dateStr + "   " + dateAfter);if (!dateStr.equals(dateAfter)) {System.out.println(dateStr + "   " + dateAfter + "   发生异常情况");}}});}}/*** 会发生异常情况的日期转换* @param pool*/public static void TestSimpleDateFormat(ExecutorService pool) {for (int i = 0; i < 100000; i++) {Date date = DateUtils.addDays(new Date(), i);pool.execute(new Thread() {@Overridepublic void run() {String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");/*** SimpleDateFormat 对象,每次使用都使用新实例*/
//                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");String dateAfter = simpleDateFormat.format(date);System.out.println(dateStr + "   " + dateAfter);if (!dateStr.equals(dateAfter)) {System.out.println(dateStr + "   " + dateAfter + "   发生异常情况");}}});}}public static void TestDateFormatUtils(ExecutorService pool) {for (int i = 0; i < 100000; i++) {Date date = DateUtils.addDays(new Date(), i);pool.execute(new Thread() {@Overridepublic void run() {String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");String dateAfter = DateFormatUtils.format(date, "yyyy-MM-dd");System.out.println(dateStr + "   " + dateAfter);if (!dateStr.equals(dateAfter)) {System.out.println(dateStr + "   " + dateAfter + "   发生异常情况");}}});}}public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(1000);
//        TestDateTimeFormatter(pool);
//        TestFastDateFormat(pool);TestSimpleDateFormat(pool);
//        TestDateFormatUtils(pool);}}

3)ThreadLocal是使用空间换时间

使用ThreadLocal解决线程安全:

public class ThreadLocalDateUtil {private static final String date_format = "yyyy-MM-dd HH:mm:ss";private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>();public static DateFormat getDateFormat()  { DateFormat df = threadLocal.get(); if(df==null){ df = new SimpleDateFormat(date_format); threadLocal.set(df); } return df; } public static String formatDate(Date date) throws ParseException {return getDateFormat().format(date);}public static Date parse(String strDate) throws ParseException {return getDateFormat().parse(strDate);}  }

 

4)synchronized是使用时间换空间

public class DateSyncUtil {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static String formatDate(Date date)throws ParseException{synchronized(sdf){return sdf.format(date);} }public static Date parse(String strDate) throws ParseException{synchronized(sdf){return sdf.parse(strDate);}}
}

其中3和4代码参考:

.html


 

更多推荐

SimpleDateFormat日期转换之线程安全问题解决方案

本文发布于:2024-03-10 01:20:16,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1726653.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   安全问题   解决方案   日期   SimpleDateFormat

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!