SimpleDateFormat简介及替代方案
简介
SimpleDateFormat是一个时间格式化工具,可以将字符串格式化时间Date类型,也可以将Date类型格式化为字符串String类型,但其线程不安全。
常用方法
public final String format(Date date):将时间格式化为我们想要的字符串。
public Date parse(String source):将字符串格式化为Date类型。
代码
- format方法
static SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
static ArrayList<Date> list=new ArrayList<>();
static {
// 每个线程对应处理的Date对象
// 我将会开启10个线程
Date date1 = new Date(2011-1900, Calendar.JANUARY,1);
Date date2 = new Date(2012-1900, Calendar.JANUARY,1);
Date date3 = new Date(2013-1900, Calendar.JANUARY,1);
Date date4 = new Date(2014-1900, Calendar.JANUARY,1);
Date date5 = new Date(2015-1900, Calendar.JANUARY,1);
Date date6 = new Date(2016-1900, Calendar.JANUARY,1);
Date date7 = new Date(2017-1900, Calendar.JANUARY,1);
Date date8 = new Date(2018-1900, Calendar.JANUARY,1);
Date date9 = new Date(2019-1900, Calendar.JANUARY,1);
Date date10 = new Date(2020-1900, Calendar.JANUARY,1);
list.add(date1);
list.add(date2);
list.add(date3);
list.add(date4);
list.add(date5);
list.add(date6);
list.add(date7);
list.add(date8);
list.add(date9);
list.add(date10);
}
/**
* 线程不安全
* 线程执行前和执行后,数据不一致
*
*
**/
public void formatdemo(){
ExecutorService service= Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int t = i;
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Date date = list.get(t);
String format = SimpleDateFormatDemo.format.format(date);
System.out.println("线程"+Thread.currentThread().getName()+" 执行前: "+date);
System.out.println("线程"+Thread.currentThread().getName()+" 执行结果后:"+format);
});
}
}
- 执行结果

线程3执行前 和 执行后结果不一致,说明线程不安全
- parse方法
public void parsedemo(){
ExecutorService service= Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int t = i;
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("线程"+Thread.currentThread().getName()+" 执行结果后:"+format.parse("2021-12-12 12:23:23"));
} catch (ParseException e) {
e.printStackTrace();
}
});
}
}
- 执行结果
出现异常: Exception in thread "pool-1-thread-1" java.lang.NumberFormatException: multiple points
线程不安全
解决办法
使用ThreadLocal进行替代
代码
public static final ThreadLocal<DateFormat> df=new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
static ArrayList<Date> list=new ArrayList<>();
static {
// 每个线程对应处理的Date对象
// 我将会开启10个线程
Date date1 = new Date(2011-1900, Calendar.JANUARY,1);
Date date2 = new Date(2012-1900, Calendar.JANUARY,1);
Date date3 = new Date(2013-1900, Calendar.JANUARY,1);
Date date4 = new Date(2014-1900, Calendar.JANUARY,1);
Date date5 = new Date(2015-1900, Calendar.JANUARY,1);
Date date6 = new Date(2016-1900, Calendar.JANUARY,1);
Date date7 = new Date(2017-1900, Calendar.JANUARY,1);
Date date8 = new Date(2018-1900, Calendar.JANUARY,1);
Date date9 = new Date(2019-1900, Calendar.JANUARY,1);
Date date10 = new Date(2020-1900, Calendar.JANUARY,1);
list.add(date1);
list.add(date2);
list.add(date3);
list.add(date4);
list.add(date5);
list.add(date6);
list.add(date7);
list.add(date8);
list.add(date9);
list.add(date10);
}
/**
* 线程不安全
* 线程执行前和执行后,数据不一致
*
*
**/
public void formatdemo(){
ExecutorService service= Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int t = i;
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Date date = list.get(t);
System.out.println("线程"+Thread.currentThread().getName()+" 执行前: "+date);
System.out.println("线程"+Thread.currentThread().getName()+" 执行结果后:"+ df.get().format(date));
});
}
}
/**
* Exception in thread "pool-1-thread-1" java.lang.NumberFormatException: multiple points
* 线程不安全
**/
public void parsedemo(){
ExecutorService service= Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int t = i;
service.execute(()->{
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("线程"+Thread.currentThread().getName()+" 执行结果后:"+df.get().parse("2021-12-12 12:23:23"));
} catch (ParseException e) {
e.printStackTrace();
}
});
}
}
Gitee地址
SimpleDateFormat简介及替代方案的更多相关文章
- 1.由浅入深解析 SimpleDateFormat
一.SimpleDateFormat简介 SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (date -> text).语法分析 (text - ...
- T-3-java核心API-基础类
一.API 现成的类(程序) Java API是java(Oracle)提供的系统标准API. 第三方的jar包API,如:JUnit.jar. 可以自己开发一些API. 一般情况下任何技术都有现成的 ...
- java之正则表达式、日期操作
正则表达式和日期操作 正则表达式简介 正则表达式就是使用一系列预定义的特殊字符来描述一个字符串的格式规则,然后使用该格式规则匹配某个字符串是否符合格式要求. 作用:比如注册邮箱,邮箱有用户名和密码,一 ...
- Java 复习整理day06
Java api 章节除了一下列的常用类别的用时候查文档 1 package com.it.demo01_api; 2 3 import java.util.Scanner; 4 5 /* 6 案例: ...
- 多线程避免使用SimpleDateFormat及替代方案
先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...
- 1.NoSql简介
NoSQL,指的是非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以 ...
- Hadoop MapReduceV2(Yarn) 框架简介[转]
对于业界的大数据存储及分布式处理系统来说,Hadoop 是耳熟能详的卓越开源分布式文件存储及处理框架,对于 Hadoop 框架的介绍在此不再累述,读者可参考 Hadoop 官方简介.使用和学习过老 H ...
- Windows应用替代方案接龙
使开源软件的优势: 开源安全产品的开发.测试和发布过程完全是透明的,同时提供产品的源代码及部分的文档.通过阅读源代码,大家可以清楚地了解开源安全技术的工作原理和实现方法,在选择开源安全技术时更有把握, ...
- Java Servlet 技术简介
Java Servlet 技术简介 Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么 ...
随机推荐
- [opencv]常用阵列操作函数总结
/*=========================================================================*/ // 阵列操作 /*============ ...
- Vue.js高效前端开发 • 【Vue列表渲染】
全部章节 >>>> 文章目录 一.v-for指令 1.v-for指令使用 2.实践练习(待更新) 二.计算属性 1.计算属性创建和使用 2.实践练习(待更新) 三.侦听属性 1 ...
- .NET 云原生架构师训练营(设计原则&&设计模式)--学习笔记
目录 设计原则 设计模式 设计原则 DRY (Don't repeat yourself 不要重复) KISS (Keep it stupid simple 简单到傻子都能看懂) YAGNI (You ...
- Java链式调用
疯狂的类构造器Builder模式,链式调用 以swagger配置类为例 比如需要返回一个ApiInfo 的类,可以直接new一个ApiInfo,这样一般需要把参数都填上 或者,可以使用他的builde ...
- Kafka版本介绍Version2.4.0
1.说明 Kafka的版本从0.11.0.X到1.0.X, 再到2.0.X大版本, 其实没有经过几个版本, 只是版本号变化较大. 2.最新发布版本 截止本文章2020年2月22号发布时, Kafka ...
- Hangfire任务调度框架使用
1.HangFire简介 HangFire是一个免费简单实用的分布式后台定时调度服务,在现在.net开发中,人气算是很高的. HangFire提供了内置集成化的控制台,可以直观明了的查看作业调度情况, ...
- Centos安装与配置
一.安装 默认安装 二.配置 配置网卡 BOOTPROTO=none ONBOOT=yes IPADDR=xxx.xxx.x.xx PREFIX=24 GATEWAY=xxx.xxx.x.x DNS1 ...
- hisql orm 框架insert数据写入教程
hisql.net 官网(文档编写中) HiSql 源码(github) https://github.com/tansar/HiSql git clone https://github.com/ta ...
- Centos下安装Maven私服Nexus
dockers安装Nexus,指定访问路径(默认为/:在使用Nginx做反向代理时,最好指定访问路径),并在容器外持久化数据,避免Nexus容器升级后数据丢失. 安装并启动 docker run -d ...
- promise到底怎么理解
Promise的含义promise是异步编程的一种解决方法.所谓promise,简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果,从语法上说,promise是一个对象,从 ...