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 是什么 ...
随机推荐
- 第二十七个知识点:什么是对称密码加密的AEAD安全定义?
第二十七个知识点:什么是对称密码加密的AEAD安全定义? AEAD 在之前的博客里,Luke描述了一种被广泛使用的操作模式(ECB,CBC和CTR)对块密码.我们也可能会想我们加密方案的完整性,完整性 ...
- vue安装使用v-chart时报错解决方案
npm i v-charts echarts -S 1.在main.js中使用报以下错 liquidFill echarts/lib/visual/dataColor 找不到 出现此原因是因为版本问题 ...
- [JNI开发]使用javah命令生成.h的头文件
第一步:进入对应的.java目录 javac xxx.java 生成对应的xxx.class文件 第二步:退回到/java目录 javah -classpath . -jni 包名.类名
- 基于Spring MVC + Spring + MyBatis的【医院就诊挂号系统】
资源下载:https://download.csdn.net/download/weixin_44893902/21727306 一.语言和环境 1.实现语言: JAVA语言. 2.环境要求: MyE ...
- Kylin启动步骤
Kylin本身的启动命令比较简单, 但是由于Kylin依赖的其他组件比较多, 所以把完整的启动步骤整理一下. 1.确保集群时间同步 首先查看集群中的时间是否同步 date 如果时间不一致,需要使用如下 ...
- ClickHouse在监控系统中的应用
一.背景 这个项目是一个监控系统,主要监控主机.网络设备.应用等.主机监控的数量有1500台左右,数量还在不断增长,加上网络设备和应用,目前总共监控的指标达到近40万个. 二.问题 一开始为了快速交付 ...
- Spring @Component 注解的使用
使用说明 这个注解用于声明当前的类是一个组件类,Spring 会通过类路径扫描来自动侦测和自动装配这些组件,创建一个个 bean 后,注册到 Spring 容器中. 带 @Component 注解的类 ...
- Pytest_fixture(9)
什么是fixture fixture是pytest特有的功能,使用装饰器 @pytest.fixture 标记的函数在其他函数中能被当作参数传入并被调用. fixture有明确的名字,在其他函数,模块 ...
- python 面向对象:封装---对象的属性可以是另一个类创建的对象
# 对象封装:对象的属性可以是另一个类创建的对象 # 案例需求: # 1.士兵许三多有一把AK47 # 2.士兵用枪射击标靶 # 3.枪能装填和发射子弹 class Gun: # 分析: # 枪的属性 ...
- react中关于create-react-app2里css相关配置
先看 webpack.config.dev.js 里的相关代码: // style files regexes const cssRegex = /\.css$/; const cssModuleRe ...