温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java SimpleDateFormat线程不安全问题怎么解决

发布时间:2023-03-25 11:18:45 来源:亿速云 阅读:86 作者:iii 栏目:开发技术

本篇内容主要讲解“Java SimpleDateFormat线程不安全问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java SimpleDateFormat线程不安全问题怎么解决”吧!

    多线程SimpleDateFormat

    public class DateTest {
        //工具类中的日期组件
        private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    
        public static void main(String[] args) throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
            for (int i = 0; i < 100; i++) {
                threadPoolExecutor.execute(() -> {
                    String dateString = sdf.format(new Date());
                    try {
                        Date parseDate = sdf.parse(dateString);
                        String dateString2 = sdf.format(parseDate);
                        System.out.println(dateString.equals(dateString2));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    结果

    Java SimpleDateFormat线程不安全问题怎么解决

    原因分析

    全局变量的SimpleDateFormat,在并发情况下,存在安全性问题。

    我们通过源码看下:

    SimpleDateFormat继承了 DateFormat

    Java SimpleDateFormat线程不安全问题怎么解决

    DateFormat类中维护了一个全局的Calendar变量

    Java SimpleDateFormat线程不安全问题怎么解决

    sdf.parse(dateStr)和sdf.format(date),都是由Calendar引用来储存的。

    如果SimpleDateFormat是static全局共享的,Calendar引用也会被共享。

    又因为Calendar内部并没有线程安全机制,所以全局共享的SimpleDateFormat不是线性安全的。

    解决方法

    解决方法1

    「FastDateFormat(FastDateFormat能保证线程安全) 替换 SimpleDateFormat」

    private static final FastDateFormat sdf = FastDateFormat.getInstance(“yyyy-MM-dd HH:mm:ss”);

     测试代码如下所示:

    public class DateTest {
        //工具类中的日期组件
    //    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        private static final FastDateFormat sdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
    
        public static void main(String[] args) throws Exception {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
            for (int i = 0; i < 100; i++) {
                threadPoolExecutor.execute(() -> {
                    String dateString = sdf.format(new Date());
                    try {
                        Date parseDate = sdf.parse(dateString);
                        String dateString2 = sdf.format(parseDate);
                        System.out.println(dateString.equals(dateString2));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
            threadPoolExecutor.shutdown();
        }
    }

    打印结果:

    Java SimpleDateFormat线程不安全问题怎么解决

    解决方法2

    「使用DateTimeFormatter(DateTimeFormatter是线程安全的,java 8+支持)代替SimpleDateFormat」

    private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

    测试代码如下:

    public class DateTest {
    //工具类中的日期组件
    // private static final SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
    private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

    // private static final FastDateFormat sdf = FastDateFormat.getInstance(“yyyy-MM-dd HH:mm:ss”);

    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(10));
        for (int i = 0; i < 100; i++) {
            threadPoolExecutor.execute(() -> {
                try {
                    String dateString = sdf.format(LocalDateTime.now());
                    TemporalAccessor temporalAccessor = sdf.parse(dateString);
                    String dateString2 = sdf.format(temporalAccessor);
                    System.out.println(dateString.equals(dateString2));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        threadPoolExecutor.shutdown();
    }

    打印结果如下:

    Java SimpleDateFormat线程不安全问题怎么解决

    到此,相信大家对“Java SimpleDateFormat线程不安全问题怎么解决”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI