SimpleDateFormat非线程安全 「爱情、让人受尽委屈。」 2022-05-22 10:18 214阅读 0赞 **枝上柳绵吹又少,天涯何处无芳草** 类SimpleDateFormat主要负责日期的转换与格式化,但是在多线程的环境下,使用此类容易造成数据转换及处理的不正确,因为SimpleDateFormat类并不是线程安全的。 测试代码: import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateTest { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String[] dateStringArray = new String[]{ "2000-01-01","2000-06-01","2000-06-01","2000-11-05","2000-08-01","2014-06-01","2018-10-01","2001-11-05","2013-08-01","2013-08-21"}; MyThread[] myThreads = new MyThread[10]; for (int i = 0 ;i < myThreads.length; i++) { myThreads[i] = new MyThread(sdf,dateStringArray[i]); } for (int i = 0 ;i < 10; i++) { myThreads[i].start(); } } } class MyThread extends Thread { private SimpleDateFormat sdf; private String dateString; public MyThread(SimpleDateFormat sdf,String dateString) { super(); this.sdf = sdf; this.dateString = dateString; } @Override public void run() { try { Date dateRef = sdf.parse(dateString); String newDateString = sdf.format(dateRef).toString(); if (!newDateString.equals(dateString)) { System.out.println("ThreadName=" + this.getName() + "报错了,日期字符串:" + dateString + "转成的日期为:" + newDateString); } }catch (Exception e) { e.printStackTrace(); } } } 运行结果: ![这里写图片描述][70] 这样就有很大概率出现转换异常的问题。那么,这个问题如何解决呢? 解决异常方法一:创建多个SimpleDateFormat对象 代码: import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateTest { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String[] dateStringArray = new String[]{ "2000-01-01","2000-06-01","2000-06-01","2000-11-05","2000-08-01","2014-06-01","2018-10-01","2001-11-05","2013-08-01","2013-08-21"}; MyThread[] myThreads = new MyThread[10]; for (int i = 0 ;i < myThreads.length; i++) { myThreads[i] = new MyThread(sdf,dateStringArray[i]); } for (int i = 0 ;i < 10; i++) { myThreads[i].start(); } } } class MyThread extends Thread { private SimpleDateFormat sdf; private String dateString; public MyThread(SimpleDateFormat sdf,String dateString) { super(); this.sdf = sdf; this.dateString = dateString; } @Override public void run() { try { Date dateRef = dateTools.parse("yyyy-MM-dd",dateString); String newDateString = dateTools.format("yyyy-MM-dd",dateRef).toString(); if (!newDateString.equals(dateString)) { System.out.println("ThreadName=" + this.getName() + "报错了,日期字符串:" + dateString + "转成的日期为:" + newDateString); } }catch (Exception e) { e.printStackTrace(); } } } class dateTools { public static Date parse(String formatPattern,String dateSring) throws ParseException { return new SimpleDateFormat(formatPattern).parse(dateSring); } public static String format(String formatPattern,Date date) throws ParseException { return new SimpleDateFormat(formatPattern).format(date); } } 运行结果: ![这里写图片描述][70 1] 解决异常方法二:使用ThreadLocal类绑定到指定对象,也可以解决该问题。 测试代码: import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateTest { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String[] dateStringArray = new String[]{ "2000-01-01","2000-06-01","2000-06-01","2000-11-05","2000-08-01","2014-06-01","2018-10-01","2001-11-05","2013-08-01","2013-08-21"}; MyThread[] myThreads = new MyThread[10]; for (int i = 0 ;i < myThreads.length; i++) { myThreads[i] = new MyThread(sdf,dateStringArray[i]); } for (int i = 0 ;i < 10; i++) { myThreads[i].start(); } } } class MyThread extends Thread { private SimpleDateFormat sdf; private String dateString; public MyThread(SimpleDateFormat sdf,String dateString) { super(); this.sdf = sdf; this.dateString = dateString; } @Override public void run() { try { Date dateRef = dateTools.getSimpleDateFormat("yyyy-MM-dd").parse(dateString); String newDateString = dateTools.getSimpleDateFormat("yyyy-MM-dd").format(dateRef).toString(); if (!newDateString.equals(dateString)) { System.out.println("ThreadName=" + this.getName() + "报错了,日期字符串:" + dateString + "转成的日期为:" + newDateString); } }catch (Exception e) { e.printStackTrace(); } } } class dateTools { public static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<>(); public static SimpleDateFormat getSimpleDateFormat(String formatPattern) { SimpleDateFormat sdf = null; if (sdf == null) { sdf = new SimpleDateFormat(formatPattern); tl.set(sdf); } return sdf; } } ![这里写图片描述][70 2] 使用这两种方法,都没有出现异常,说明异常已经被我们解决了。 [70]: /images/20220522/e0759cd390e54398a23464b6a5dc0af2.png [70 1]: /images/20220522/d5d2ee9dd5784296b369d32c89707b16.png [70 2]: /images/20220522/64bdd094c3d6439a8fff5e9b361dc34a.png
还没有评论,来说两句吧...