共享模型之不可变阶段七

本文探讨了Java中的日期转换问题及其线程不安全的解决方案,强调了不可变对象在确保线程安全中的作用。介绍了final关键字在创建不可变对象中的应用,如DateTimeFormatter和String类。此外,文章还讨论了享元模式在对象重用中的应用,以及自定义连接池的实现。最后,阐述了final变量的原理和无状态类的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7.1 日期转换的问题

问题提出,下面的代码在运行时,由于 SimpleDateFormat 不是线程安全的,有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果。

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    log.debug("{}", sdf.parse("1951-04-21"));
                } catch (Exception e) {
                    log.error("{}", e);
                }
            }).start();
        }

 有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果,例如:

 解决方案

方案一:加锁

 方案二:使用DateTimeFormatter

思路 - 不可变对象

如果一个对象在不能够修改其内部状态(属性),那么它就是线程安全的,因为不存在并发修改,这样的对象在 Java 中有很多,例如在 Java 8 后,提供了一个新的日期格式化类DateTimeFormatter:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                LocalDate date = dtf.parse("2018-10-01", LocalDate::from);
                log.debug("{}", date);
            }).start();
        }

7.2 不可变设计

  1. 更多不可变类的知识,可参考这这里
  2. final类的知识,参考这里

另一个大家更为熟悉的 String 类也是不可变的,以它为例,说明一下不可变类设计的要素

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    /** Cache the hash code for the string */
    private int hash; // Default to 0
    // ...
}

final 的使用

发现该类、类中所有属性都是 final 的

属性用 final 修饰保证了该属性是只读的,不能修改

类用 final 修饰保证了该类中的方法不能被覆盖,防止子类无意间破坏不可变性

保护性拷贝

String的构造方法,传递字符串数组,通过数组拷贝实现数据的安全性,这也是一种保护性拷贝。如果其他线程都用同一个数组,那么其他线程修改了那数据就不能保证数据的安全性。

但有同学会说,使用字符串时,也有一些跟修改相关的方法啊,比如 substring 等,那么下面就看一看这些方法是 如何实现的,就以 substring 为例:

 public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.l
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值