类SimpleDateFormat主要负责日期的格式化和转换,但是在多线程的环境中,使用此类容易造成数据转换和处理不正确,因为SimpleDateFormat类并不是线程安全的。

  • 1简单示例,出现异常
package com.test.test4;import java.text.SimpleDateFormat;/*** SimpleDateFormat非线程安全* Created by admin on 2018/12/18.*/
public class Test {public static void main(String[] args) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};MyThread[] threadArray = new MyThread[5];for (int i=0;i<5;i++) {threadArray[i] = new MyThread(sdf,dataStringArray[i]);}for (int i=0;i<5;i++) {threadArray[i].start();}}}package com.test.test4;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Created by admin on 2018/12/18.*/
public class MyThread extends Thread {private SimpleDateFormat sdf;private String dateString;public MyThread(SimpleDateFormat sdf,String dateString){super();this.sdf = sdf;this.dateString = dateString;}@Overridepublic 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 (ParseException e) {e.printStackTrace();}}}

  •   运行结果
ThreadName=Thread-4报错了 日期字符串:2000-01-05转换成的日期为0001-01-02
ThreadName=Thread-2报错了 日期字符串:2000-01-03转换成的日期为0001-01-02
ThreadName=Thread-0报错了 日期字符串:2000-01-01转换成的日期为0001-01-02
ThreadName=Thread-3报错了 日期字符串:2000-01-04转换成的日期为0001-01-02Process finished with exit code 0

  •   解决异常办法一:解决处理错误的原理是创建了多个SimpleDateFormat
public class Test {public static void main(String[] args) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};MyThread[] threadArray = new MyThread[5];for (int i=0;i<5;i++) {threadArray[i] = new MyThread(sdf,dataStringArray[i]);}for (int i=0;i<5;i++) {threadArray[i].start();}}}package com.test.formatOk1;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Created by admin on 2018/12/18.*/
public class DateTools {public static Date parse(String formatPattern, String dataString) throws ParseException{return new SimpleDateFormat(formatPattern).parse(dataString);}public static String format(String formatPattern,Date date){return new SimpleDateFormat(formatPattern).format(date).toString();}}package com.test.formatOk1;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Created by admin on 2018/12/18.*/
public class MyThread extends Thread {private SimpleDateFormat sdf;private String dateString;public MyThread(SimpleDateFormat sdf,String dateString){super();this.sdf = sdf;this.dateString = dateString;}@Overridepublic 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 (ParseException e) {e.printStackTrace();}}}

  解决异常办法二:ThreadLocal类能使线程绑定到指定对象,使用ThreadLocal也可以处理这种错误

package com.test.formatOk2;import java.text.SimpleDateFormat;/*** SimpleDateFormat非线程安全* Created by admin on 2018/12/18.*/
public class Test {public static void main(String[] args) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String[]dataStringArray = new String[]{"2000-01-01","2000-01-02","2000-01-03","2000-01-04","2000-01-05"};MyThread[] threadArray = new MyThread[5];for (int i=0;i<5;i++) {threadArray[i] = new MyThread(sdf,dataStringArray[i]);}for (int i=0;i<5;i++) {threadArray[i].start();}}}package com.test.formatOk2;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Created by admin on 2018/12/18.*/
public class DateTools {private static ThreadLocal<SimpleDateFormat> t1 = new ThreadLocal<SimpleDateFormat>();public static SimpleDateFormat getSimpleDateFormat(String datePattern){SimpleDateFormat sdf = null;sdf = t1.get();if (sdf == null) {sdf = new SimpleDateFormat(datePattern);t1.set(sdf);}return sdf;}}package com.test.formatOk2;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Created by admin on 2018/12/18.*/
public class MyThread extends Thread {private SimpleDateFormat sdf;private String dateString;public MyThread(SimpleDateFormat sdf,String dateString){super();this.sdf = sdf;this.dateString = dateString;}@Overridepublic 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 (ParseException e) {e.printStackTrace();}}}

  

转载于:https://www.cnblogs.com/airycode/p/10135136.html

SimpleDateFormat非线程安全相关推荐

  1. wamp php非线程安全,wampserver PHP多版本切换

    1.从官网下载一个php7包,如php7.3.10,官网地址http://windows.php.net/download/ (注意选择 TS / NTS版本) 2.将刚下载的压缩包解压缩,修改命名为 ...

  2. Java:代码验证 StringBuffer 线程安全,StringBuilder 非线程安全

    首先需要明白什么是线程安全,什么是非线程安全,引用百度百科  关于 Java 中 String,StringBuffer 和 StringBuilder 的区别,参看:  Java:String,St ...

  3. 非线程安全类ArrayList出现异常:java.util.ConcurrentModificationException

    今天执行了一段<图解多线程设计模式>中的代码,结果抛出了如下的异常: Exception in thread "ReaderThread" java.util.Conc ...

  4. PHP----------线程安全和非线程安全的介绍

    1.Linux下的PHP,没有线程安全版和非线程安全版之分.从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,直至5.2.1版本开始有Thread Sa ...

  5. Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)

    前言: 在前面的系列中,我们虽然完成了其大部分功能,但是,离正真运行,还是有一大段距离 当你F5运行时,在弹出对话框之后,如果你不即时点确定,或者上个WC回来之后,你会发现已经提示出错了 这节开始,我 ...

  6. Java非线程安全问题的解决方法

    非线程安全.非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改.值不同步的情况,进而影响程序的执行流程.下面用一个示例来学习一下如何解决非线程安全问题. 本案例模拟了多线 ...

  7. PHP线程安全和非线程安全的区别

    Windows版的PHP从版本5.2.1开始有Thread Safe.这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. 从2000年10月20日发布的第一个Windows版的PHP3.0.1 ...

  8. 【java的socket编程】结合多线程Thread实现通信(使用线程池和非线程池对比)、java开发UDP/IP网络程序

    结合多线程实现socket 使用非线程池(拓展Thread) 使用线程池(Executor pool) 使用DatagramPacket DatagramSocket开发UDP/IP程序 使用UDP获 ...

  9. php+linux+线程安全,PHP 线程安全与非线程安全版本的区别深入解析

    从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,这是由于与Linux/Unix系统是采用多进程的工作方式不同的是Windows系统是采用多线程的工作方 ...

最新文章

  1. 微软,一个分裂的存在
  2. php yield 递归,递归运行所有yield请求h的废弃输出文件
  3. python英文单词-python常用150个英文单词
  4. python 新闻摘要_每日新闻摘要:Microsoft内部禁止应用程序,这样就可以了
  5. 常用公有云接入——谷歌
  6. python 图片识别_python识别图片文字
  7. AJAX入门——工作原理
  8. SpringBoot项目利用maven自定义打包结构
  9. 是否有“他们的”版本的“git merge -s ours”?
  10. 华为携西班牙电信于智利设立NB-IoT开放实验室
  11. 深入浅出 卡尔曼滤波
  12. 一个基于高阶图匹配的多目标跟踪器:Online Multi-Target Tracking with Tensor-Based High-Order Graph Matching
  13. Minigui实现半透效果
  14. 不懂怎么搞定人的进来:年业绩千万的老销售给你几招实惠的-没有干货立即跳楼
  15. 计算机开机的四个画面,教你修改电脑开机时“欢迎使用”四个字!
  16. 鸿蒙桌面系统什么时候上线,鸿蒙OS全新PC桌面模式即将上线?回顾一下手机桌面系统的发展历程...
  17. mysql绘制er图菱形表示什么意思_ER图中菱形表示的是()
  18. 相亲小程序如何做到年入百万?盈利模式是什么?
  19. Anaconda 安装与 使用
  20. 给我半首歌的时间,给你说明白Immutable List

热门文章

  1. 网站正在建设中提示页面设计欣赏
  2. FCKeditor的开发精简
  3. Groovy 设计模式 -- 抽象工厂 模式
  4. ionic移动开发流程api
  5. Mybatis接口注解开发
  6. 计时器Chronometer和时钟(AnalogClock和DigitalClock)
  7. [译]NectarJS:编译JavaScript为任意平台原生二进制代码
  8. 永信至诚携 “企业安全人才培养解决方案”惊艳WOT技术峰会
  9. php性能优化二(PHP配置php.ini)
  10. ActiveMQ消息传送机制以及ACK机制详解