让DateFormat多线程安全

2024-06-13 00:32
文章标签 安全 多线程 dateformat

本文主要是介绍让DateFormat多线程安全,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

"DateFormat 不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。"----摘自JDK文档中文版

首先让我们看看一个简单的方法

public static Date toDate(String dateStr) {
SimpleDateFormat p= new SimpleDateFormat("yyyyMMdd");
try{
return p.parse(dateStr);
}catch (ParseException e) {
}
return null;
}


这个方法是把形如"20110101"这样的字符串转换成Date类型;同时方法是支持多线程并发访问的,但是这个是有代价的,因为每次方法调用都要创建一个SimpleDateFormat 对象。

很自然的我们就想到以下的改进,将SimpleDateFormat声明为静态全局变量

private static final SimpleDateFormat PATTERN = new SimpleDateFormat("yyyyMMdd");

同时为了保证多线程同步访问,方法需要加锁

public synchronied static Date toDate(String dateStr) {
try{
return PATTERN.parse(dateStr);
}catch (ParseException e) {
}
return null;
}



这样的优化还是不够的,因为在多线程争用的情况下,性能不佳。最好是每个线程都有自己的DateFormat,这样既不会发生争用,而且对于每个线程都只创建一个DateFormat对象。
ThreadLocal正好可以满足这种需求。这里不多做解释了,我们一步到位:

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class DateFormatFactory {
private static final Map<String, ThreadLocal<SimpleDateFormat>> pool = new HashMap<String, ThreadLocal<SimpleDateFormat>>();
private static final Object lock = new Object();

public static SimpleDateFormat getDateFormat(String pattern) {
ThreadLocal<SimpleDateFormat> tl = pool.get(pattern);
if (tl == null) {
synchronized (lock) {
tl = pool.get(pattern);
if (tl == null) {
final String p = pattern;
tl = new ThreadLocal<SimpleDateFormat>() {
protected synchronized SimpleDateFormat initialValue() {
return new SimpleDateFormat(p);
}
};
pool.put(p, tl);
}
}
}
return tl.get();
}
}

public static Date toDate(String dateStr,String pattern) {
try{
return getDateFormat(pattern).parse(dateStr);
}catch (ParseException e) {
}
return null;
}


上面还增加了对不同Pattern的ThreadLocal的缓存,这样对于每一个线程每一种pattern都只要创建一个SimpleDateFormat对象,多线程访问无需争用。

代码还要很多待改进的地方,如对于非法的pattern不要缓存,是否存在更快、更节约内存的方法。。。。。。
匆匆忙忙,如有错误的地方望不吝赐教!

这篇关于让DateFormat多线程安全的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1055776

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2