• SimpleDateFormat线程不安全的5种解决方案


    1.什么是线程不安全?

    线程不安全也叫非线程安全,是指多线程执行中,程序的执行结果和预期的结果不符的情况就叫着线程不安全。

    线程不安全的代码

    SimpleDateFormat 就是一个典型的线程不安全事例,接下来我们动手来实现一下。首先我们先创建 10 个线程来格式化时间,时间格式化每次传递的待格式化时间都是不同的,所以程序如果正确执行将会打印 10 个不同的值,接下来我们来看具体的代码实现:

    import java.text.SimpleDateFormat; 
    import java.util.Date; 
    import java.util.concurrent.ExecutorService; 
    import java.util.concurrent.Executors; 
     
    public class SimpleDateFormatExample { 
        // 创建 SimpleDateFormat 对象 
        private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss"); 
     
        public static void main(String[] args) { 
            // 创建线程池 
            ExecutorService threadPool = Executors.newFixedThreadPool(10); 
            // 执行 10 次时间格式化 
            for (int i = 0; i < 10; i++) { 
                int finalI = i; 
                // 线程池执行任务 
                threadPool.execute(new Runnable() { 
                    @Override 
                    public void run() { 
                        // 创建时间对象 
                        Date date = new Date(finalI * 1000); 
                        // 执行时间格式化并打印结果 
                        System.out.println(simpleDateFormat.format(date)); 
                    } 
                }); 
            } 
        } 
    } 

    我们预期的正确结果是这样的(10 次打印的值都不同):

    然而,以上程序的运行结果却是这样的:

    从上述结果可以看出,当在多线程中使用 SimpleDateFormat 进行时间格式化是线程不安全的。

    2.解决方案

    SimpleDateFormat 线程不安全的解决方案总共包含以下 5 种:

    1. 将 SimpleDateFormat 定义为局部变量;
    2. 使用 synchronized 加锁执行;
    3. 使用 Lock 加锁执行(和解决方案 2 类似);
    4. 使用 ThreadLocal;
    5. 使用 JDK 8 中提供的 DateTimeFormat。

    接下来我们分别来看每种解决方案的具体实现。

    ① SimpleDateFormat改为局部变量

    将 SimpleDateFormat 定义为局部变量时,因为每个线程都是独享 SimpleDateFormat 对象的,相当于将多线程程序变成“单线程”程序了,所以不会有线程不安全的问题,具体实现代码如下:

  • 相关阅读:
    synchronized优化手段:锁膨胀、锁消除、锁粗化和自适应自旋锁...
    synchronized 优化手段之锁膨胀机制!
    synchronized 加锁 this 和 class 的区别!
    SpringBoot中时间格式化的5种方法!
    阿里云ddns shell 脚本
    adb 备份apk
    paddlex_gui_win10(飞浆)
    cuda 版本对照
    PaddleHub
    yum 查找库对应的包
  • 原文地址:https://www.cnblogs.com/rinack/p/14779561.html
Copyright © 2020-2023  润新知