SimpleDateFormat-多线程问题
SimpleDateFormat-多线程问题:
SimpleDateFormat类在多线程环境下中处理日期,极易出现日期转换错误的情况
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; /**
* 线程类
*/
public class MyThread extends Thread { private SimpleDateFormat sdf;
private String dateString; public MyThread(SimpleDateFormat sdf,String dateString) {
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 = " + Thread.currentThread().getName()
+ "报错了 日期字符串:" + dateString + "转换成日期为:" + newDateString);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
import java.text.SimpleDateFormat;
public class Test {
/**
* 测试单例的SimpleDateFormat类在多线程环境下中处理日期,极易出现日期转换错误的情况
*/
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String[] dateStringArray = new String[] {
"2000-01-01","2000-01-02","2000-01-03",
"2000-01-04","2000-01-05","2000-01-06",
"2000-01-07","2000-01-08","2000-01-09",
"2000-01-10"
};
MyThread[] threadArray = new MyThread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new MyThread(sdf, dateStringArray[i]);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
运行之后会输出很多的错误信息!
解决多线程出现的问题-为每个线程实例一个SimpleDateFormat:
import java.text.ParseException;
import java.util.Date; /**
* 线程类
*/
public class MyThread extends Thread { private String dateString;
public MyThread(String dateString) {
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 = " + Thread.currentThread().getName()
+ "报错了 日期字符串:" + dateString + "转换成日期为:" + newDateString);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; /**
* 日期格式化工具类
*/
public class DateTools { public static Date parse(String formatPattern,String dateString) throws ParseException {
return new SimpleDateFormat(formatPattern).parse(dateString);
} public static String format(String formatPattern,Date date) throws ParseException {
return new SimpleDateFormat(formatPattern).format(date).toString();
}
}
public class Test {
/**
* 测试,运行程序后,控制台没有任何输出,也就是转换没有任何异常,
* 原理:创建了多个SimpleDateFormat实例
*/
public static void main(String[] args) {
String[] dateStringArray = new String[] {
"2000-01-01","2000-01-02","2000-01-03",
"2000-01-04","2000-01-05","2000-01-06",
"2000-01-07","2000-01-08","2000-01-09",
"2000-01-10"
};
MyThread[] threadArray = new MyThread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new MyThread(dateStringArray[i]);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
解决多线程出现的问题-使用ThreadLocal:
import java.text.ParseException;
import java.util.Date; /**
* 线程类
*/
public class MyThread extends Thread { private String dateString;
public MyThread(String dateString) {
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 = " + Thread.currentThread().getName()
+ "报错了 日期字符串:" + dateString + "转换成日期为:" + newDateString);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
import java.text.SimpleDateFormat; /**
* 日期格式化工具类,使用ThreadLocal解决SimpleDateFormat非线程安全问题
*/
public class DateTools { private static ThreadLocal<SimpleDateFormat> t1 = new ThreadLocal<>(); public static SimpleDateFormat getSimpleDateFormat(String datePattern) {
SimpleDateFormat sdf = null;
sdf = t1.get();
if(sdf == null) {
sdf = new SimpleDateFormat(datePattern);
t1.set(sdf);
}
return sdf;
}
}
public class Test {
/**
* 测试,运行程序后,控制台没有任何输出,也就是转换没有任何异常
* 原理:每个线程都会有自己的ThreadLocal存储全局变量,也就是每个线程都有自己的SimpleDateFormat实例
*/
public static void main(String[] args) {
String[] dateStringArray = new String[] {
"2000-01-01","2000-01-02","2000-01-03",
"2000-01-04","2000-01-05","2000-01-06",
"2000-01-07","2000-01-08","2000-01-09",
"2000-01-10"
};
MyThread[] threadArray = new MyThread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new MyThread(dateStringArray[i]);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
SimpleDateFormat-多线程问题的更多相关文章
- ThreadLocal解决SimpleDateFormat多线程安全问题中遇到的困惑
测试代码: public class Main { public static void main(String[] args) { for (int k = 0; k < 10; k++) { ...
- java 多线程:线程安全问题,示例DateFormat多线程执行冲突解决方案ThreadLocal、方法内变量
SimpleDateFormat多线程中执行报错 java.lang.NumberFormatException: For input string: "" import ja ...
- JEECG 3.7.1 版本发布,企业级JAVA快速开发平台
JEECG 3.7.1 版本发布,企业级JAVA快速开发平台 ---------------------------------------- Version: Jeecg_3.7.1项 目: ...
- ThreadLocal知识点
ThreadLocal是什么 ThreadLocal 表面上看他是和多线程,线程同步有关的一个工具类,但其实他与线程同步机制无关.线程同步机制是多个线程共享同一个变量,而ThreadLocal是为每个 ...
- JAVA中计算两个日期时间的差值竟然也有这么多门道
上半年春招的时候,作为面试官,对于面试表现的不错的同学会要求其写一小段代码看看.题目很简单: 给定一个日期,然后计算下距离今天相差的天数. 本以为这么个问题就是用来活跃面试氛围的,但是结果却让人大跌眼 ...
- SimpleDateFormat做成员或者静态成员多线程安全隐患
转自:http://blog.csdn.net/jeamking/article/details/7183958 有时我们在同一个类中都是使用同一种日期格式,又或者为了减少new SimpleDate ...
- 【多线程补充】SimpleDateFormat非线程安全与线程中、线程组中异常的处理
1.SimpleDateFormat非线程安全的问题 类SimpleDateFormat主要负责日期的转换与格式化,但在多线程环境中,使用此类容易造成数据转换及处理的不正确,因为SimpleDateF ...
- Java多线程:SimpleDateFormat
一.SimpleDateFormat的线程安全问题 为什么SimpleDateFormat是线程不安全的? 下面通过一个案例代码来说明 public class DateUtilTest { publ ...
- Java多线程(三)SimpleDateFormat
多线程报错:java.lang.NumberFormatException: multiple points SimpleDateFormat是非线程安全的,在多线程情况下会有问题,在每个线程下得各自 ...
- 多线程避免使用SimpleDateFormat及替代方案
先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...
随机推荐
- 编译内核时覆盖KBUILD_BUILD_USER和KBUILD_BUILD_HOST
默认情况下make kernel.img编译出来的内核在/proc/version中显示的内容是: Linux version 3.0.36+ (xxx@yyyy) (gcc version 4.6. ...
- 格式化SQL和逆格式SQL
上篇说过SQLyog中的计算合适数据类型的功能,现在说下Navicat格式化SQL和逆格式化SQL 啥也不说了,一看图,一目了然,Beautify SQL(格式化,即变成最美的语句)和Minify S ...
- 解析Ceph: RBDCache 背后的世界
转自:https://www.ustack.com/blog/ceph-internal-rbdcache/ RBDCache 是Ceph的块存储接口实现库 Librbd 的用来在客户端侧缓存数据的目 ...
- iTextSharp 生成PDF
下载地址:http://sourceforge.net/projects/itextsharp/ iText is a PDF library that allows you to CREATE, A ...
- 让您的Chrome浏览器允许本地环境支持Ajax
对于网站前端人员来说,我们在本地开发程序的时候如果用到Ajax的话,通常会使用Firefox来测试,因为Firefox的安全策略支持本地Ajax,IE系列和Chrome都不支持. 不过,经过笔者亲身体 ...
- 2018.7.27 wireless charger TX evaluation kit based on STWBC-EP
1 introduced 我们需要设计一个无线充电方案: 功能需求:通用的无线充电平台 参数要求:8-10W step1: 找寻资料 http://www.ti.com/sitesearch/doc ...
- spring学习-3
spring的自动装配 spring IOC容器可以自动装配bean,只需要在bean的autowire属性指定自动装配的模式. 模式: 1.byType:根据类型自动装配.根据bean的类型和当前b ...
- 如何加快Json 序列化?有哪些方法?
1.使用阿里的fastjson 2.可以通过去除不必要属性加快序列化.如person对象,有id,name,address,我json需要用户姓名,此时序列化的时候就只序列化name,id和addre ...
- Yii 常用命令
一.Yii的Active Recorder包装了很多. 特别是把SQL中 把where,order,limit,IN/not IN,like等常用短句都包含进CDbCriteria这个类中去,这样整个 ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...