简介

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地址

https://gitee.com/zhuayng/foundation-study/tree/develop/JavaBasis/Tools/src/main/java/com/yxkj/javabasistools/tools/date

SimpleDateFormat简介及替代方案的更多相关文章

  1. 1.由浅入深解析 SimpleDateFormat

    一.SimpleDateFormat简介 SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (date -> text).语法分析 (text - ...

  2. T-3-java核心API-基础类

    一.API 现成的类(程序) Java API是java(Oracle)提供的系统标准API. 第三方的jar包API,如:JUnit.jar. 可以自己开发一些API. 一般情况下任何技术都有现成的 ...

  3. java之正则表达式、日期操作

    正则表达式和日期操作 正则表达式简介 正则表达式就是使用一系列预定义的特殊字符来描述一个字符串的格式规则,然后使用该格式规则匹配某个字符串是否符合格式要求. 作用:比如注册邮箱,邮箱有用户名和密码,一 ...

  4. Java 复习整理day06

    Java api 章节除了一下列的常用类别的用时候查文档 1 package com.it.demo01_api; 2 3 import java.util.Scanner; 4 5 /* 6 案例: ...

  5. 多线程避免使用SimpleDateFormat及替代方案

    先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...

  6. 1.NoSql简介

    NoSQL,指的是非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以 ...

  7. Hadoop MapReduceV2(Yarn) 框架简介[转]

    对于业界的大数据存储及分布式处理系统来说,Hadoop 是耳熟能详的卓越开源分布式文件存储及处理框架,对于 Hadoop 框架的介绍在此不再累述,读者可参考 Hadoop 官方简介.使用和学习过老 H ...

  8. Windows应用替代方案接龙

    使开源软件的优势: 开源安全产品的开发.测试和发布过程完全是透明的,同时提供产品的源代码及部分的文档.通过阅读源代码,大家可以清楚地了解开源安全技术的工作原理和实现方法,在选择开源安全技术时更有把握, ...

  9. Java Servlet 技术简介

    Java Servlet 技术简介 Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么 ...

随机推荐

  1. 使用.NET 6开发TodoList应用(11)——使用FluentValidation和MediatR实现接口请求验证

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在响应请求处理的过程中,我们经常需要对请求参数的合法性进行校验,如果参数不合法,将不继续进行业务逻辑的处理.我们当然可以将每个 ...

  2. <学习opencv>跨平台和本机windows

    /*=========================================================================*/ // 跨平台和本机Windows /*=== ...

  3. 生成对抗网络GAN与DCGAN的理解

    作者在进行GAN学习中遇到的问题汇总到下方,并进行解读讲解,下面提到的题目是李宏毅老师机器学习课程的作业6(GAN) 一.GAN 网络上有关GAN和DCGAN的讲解已经很多,在这里不再加以赘述,放几个 ...

  4. HTML网页设计基础笔记 • 【目录】

    持续更新中- 我的大学笔记>>> 章节 内容 第1章 HTML网页设计基础笔记 • [第1章 HTML5基础] 第2章 HTML网页设计基础笔记 • [第2章 排列页面内容] 第3章 ...

  5. html基础 有语义的布局标签

  6. ConfigParser_读取配置文件信息

    ConfigParse简介 ConfigParser 在python中是用来解析配置文件的内置模块,直接导入使用 import configparser 使用该模块可以对配置文件进行增.读.改.删操作 ...

  7. PowerShell【变量篇】

    PS C:\Users\Administrator> $str='这是一个变量' PS C:\Users\Administrator> $str 这是一个变量 PS C:\Users\Ad ...

  8. PowerShell 管道符之Where-Object的使用方法

    1 Get-Process|Select-Object -Property Name|Where-Object{$_ -match 'QQ'} 可以匹配到QQ为名的结果

  9. java.exe and -classpth or -cp

    mydirname=$(dirname $0) java -cp $classes_dir:$lib_dir/*:$config_dir -Doracle.net.wallet_location=${ ...

  10. reduce/reduceRight

    使用 reduce 和 reduceRight 方法可以汇总数组元素的值,具体用法如下: reduce function appendCurrent (previousValue, currentVa ...