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 是什么 ...
随机推荐
- 【机器学*】k*邻算法-01
k临*算法(解决分类问题): 已知数据集,以及该数据对应类型 给出一个数据x,在已知数据集中选择最接*x的k条数据,根据这k条数据的类型判断x的类型 具体实现: from numpy import * ...
- CS5265替代LT8711设计TYPEC转HDMI 4K高清投屏方案|LT8711龙迅替代方案
龙迅LT8711是一款Type-C/DP1.2 to HDMI2.0方案芯片.LT8711HE是一款高性能Type-C/DP1.2至HDMI2.0转换器,设计用于将USB typec或DP1.2源连接 ...
- 【】VMware vSphere中三种磁盘规格的解释说明
在VMware vSphere中,不管是以前的5.1版本,或者是现在的6.5版本,创建虚拟机时,在创建磁盘时,都会让选择磁盘的置备类型,如下图所示,分为: 厚置备延迟置零 厚置备置零 Thin Pro ...
- EntityFrameworkCore数据迁移(一)
.net core出来已经有很长一段时间了,而EentityFrameworkCore(后面简称EFCore)是.net framework的EntityFramework在.net core中的实现 ...
- CentOS 系统 查看 cpu核数
转载自 :Centos下查看cpu核数 - 韩憨 - 博客园 (cnblogs.com) 1.概念物理CPU:实际Server中插槽上的CPU个数.物理cpu数量:可以数不重复的 physical i ...
- 初识python 之 取101到200之前的所有素数
素数:只能被1或本身整除 思路分析:这个数只有2个数据能整除 代码如下: n = 0 li = [] for i in range(101,200): m = 0 for j in range(1,2 ...
- linux 查看历史命令 history命令
1.history命令 "history"命令就是历史记录.它显示了在终端中所执行过的所有命令的历史. history //显示终端执行过的命令 history 10 //显示最近 ...
- nuxt服务端渲染
<template> <div class="page"> page is search <ul> <li v-for="(it ...
- 【Java】comparable、comparator
comparable.comparator接口 说明 Java中的对象,正常情况下,只能进行比较:== 或 != .不能使用 > 或 < 的,但是在开发场景中,我们需要对多个对象进行排序, ...
- 一网打尽JVM垃圾回收知识体系
垃圾回收的区域 堆:Java 中绝大多数的对象都存放在堆中,是垃圾回收的重点 方法区:此中的 GC 效率较低,不是重点 由于虚拟机栈的生命周期和线程一致,因此不需要 GC 对象判活 在垃圾收集器对堆进 ...