首页 > 其他分享 >SimpleDateFormat线程安全性

SimpleDateFormat线程安全性

时间:2023-10-13 23:14:25浏览次数:27  
标签:private SimpleDateFormat static RESULT new 线程 安全性

SimpleDateFormat线程安全性

0

结论

SimpleDateFormat是线程不安全的。

在JDK中关于SimpleDateFormat有这样一段描述:

Date formats are not synchronized.
It is recommended to create separate format instances for each thread.
If multiple threads access a format concurrently, it must be synchronized
externally.
@apiNote Consider using {@link java.time.format.DateTimeFormatter} as an
immutable and thread-safe alternative.

原因

SimpleDateFormat通过父类DateFormat中的calendar对象变量保存要格式化的时间,calendar定义代码:

protected Calendar calendar;

calendar的定义和SimpleDateFormat使用calendar变量都没有考虑线程安全。

验证

代码

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

public class SimpleDateFormatTest {
    private static final DateFormat STATIC_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    private static final Date NOW = new Date();

    private static final Date TOMORROW = new Date(NOW.getTime() + 24 * 3600 * 1000);

    private static final Set<String> NOW_RESULT = new HashSet<>();

    private static final Set<String> TOMORROW_RESULT = new HashSet<>();

    private static final int THREAD_COUNT = 10;

    private static final CountDownLatch COUNT_DOWN_LATCH = new CountDownLatch(THREAD_COUNT);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < THREAD_COUNT; i++) {
            new Thread(SimpleDateFormatTest::run).start();
        }

        COUNT_DOWN_LATCH.await();

        System.out.println(NOW_RESULT);
        System.out.println(TOMORROW_RESULT);
    }

    private static void run() {
        for (int i = 0; i < 100; i++) {
            NOW_RESULT.add(STATIC_DATE_FORMAT.format(NOW));
            TOMORROW_RESULT.add(STATIC_DATE_FORMAT.format(TOMORROW));
        }
        COUNT_DOWN_LATCH.countDown();
    }
}

输出

[20230916, 20230917]
[20230916, 20230917]

结果说明

NOW_RESULT应该只有当天的日期字符串,TOMORROW_RESULT应该只有第二天的日期字符串,但结果是这两个Set中既包含当天又包含第二天的字符串。

STATIC_DATE_FORMAT作为static变量,在所有的线程中共享,导致不同线程设置的时间错乱,结果不准确。

标签:private,SimpleDateFormat,static,RESULT,new,线程,安全性
From: https://www.cnblogs.com/u6b66/p/17763485.html

相关文章

  • 并行编程-1.托管线程概念
    .NET线程基础知识是时候开始学习C#和.NET中的线程基础知识了。我们将介绍.NET6中可用的托管线程概念,但其中许多功能从一开始就是.NET的一部分。System.Threading命名空间从.NETFramework1.0开始可用。在随后的20年中,为开发人员添加了许多有用的功能。为了在......
  • 多线程逆向
    一.资料检索以及归纳XDBG调试时默认是只运行下断调试的线程其它线程处于暂停挂起状态属于单线程调试。打开线程窗口可以查看线程挂起计数(+号-号快捷键可以挂起恢复线程)双击线程可进入选择线程,如果要调试指定线程的话我的理解是应该在线程代码中下断(线程的各种系统CALL),线程会自......
  • [转载]jmeter - 如何在指定数量的线程失败后停止 Jmeter 测试
     原地址https://www.coder.work/article/7090277  我有一个事务Controller,它在我的Jmeter测试计划中有一个http请求。交易名称和url来自CSV文件。最后,总执行分为5个不同的事务。测试计划:测试计划-线程组-用户定义的变量总样本执行量为8000-10000。现在......
  • Nacos 实现动态化线程池,真香!
    在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配......
  • C语言 - 使用_beginthreadex()创建线程
    经过了解才知道,C++03之前,用的创建线程都是CreateThread与_beginthreadex。使用这个两个函数进行创建线程。然后C++11之后,就出现了新的线程函数thread,当然,这个创建线程比较方便!经过两三天的纠结,最终决定深入研究_beginthreadex此方式创建线程,具体为什么我也说不清楚,看到网上很多......
  • 面试官:ConcurrentHashMap 是如何保证线程安全的
    1、前言阅读此篇文章,你需要有以下知识基础Java内存模型,可见性问题CASHashMap底层原理我们知道,在日常开发中使用的HashMap是线程不安全的,而线程安全类HashTable只是简单的在方法上加锁实现线程安全,效率低下,所以在线程安全的环境下我们通常会使用ConcurrentHashMap,但是又为何需要学习......
  • Java 线程池
    目录线程池线程池创建方式通过ThreadPoolExecutor创建线程池ThreadPoolExecutor的总体设计ThreadPoolExecutor的继承关系ThreadPoolExecutor的运行机制ThreadPoolExecutor生命周期管理任务执行机制线程池线程池就是管理一系列线程的资源池。当有任务要处理时,直接从线程池......
  • C++ - 多线程之线程管理函数
    1.获取线程id函数get_id()的使用该函数在命名空间std::this_thread下。作用是获取当前线程的id。#include<iostream>#include<thread>usingnamespacestd;//No.1get_id()获取线程idvoidthreadFunc(){ cout<<"get_id()子线程id:"<<this_thread::get_id(......
  • C++ - 多线程之带返回值的线程处理函数
    1.使用async函数创建线程1.1使用步骤使用async函数启动一个异步任务(创建线程,并且执行线程处理函数),返回future对象通过future对象中get()方法获取线程处理函数的返回值1.2基本数据类型作为返回值#include<iostream>#include<thread>#include<future>using......
  • C++ - 多线程之线程同步
    1.多线程的并发问题线程间为什么需要同步?直接来看一个例子:inta=0;voidfoo(){ for(inti=0;i<10000000;++i) { a+=1; }}intmain(){ clock_tstart,end; start=clock(); threadt1(foo); threadt2(foo); t1.join(); t2.join(); end=clock();......