Immutable设计 SimpleDateFormat DateTimeFormatter
专栏系列文章地址:https://blog.csdn.net/qq_26437925/article/details/145290162
本文目标:
- 理解不可变设计模式,时间format有线程安全要求的注意使用DateTimeFormatter
目录
- Immutable
- SimpleDateFormat 非线程安全
- 可以`synchronized`解决,但效率低
- DateTimeFormatter 线程安全
- 线程安全原理
- 其它不可变设计模式例子
- Java String类为什么是final的?
Immutable
英[ɪˈmjuːtəbl]
美[ɪˈmjuːtəbl]
adj.
不变的;不可改变的;
例句
They free our minds from considering our world as fixed and immutable.
它们改变着人们将世界看作是永恒不变的观点。
SimpleDateFormat 非线程安全
例子代码
static void test1(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
Date date = dateFormat.parse("1999-09-09");
System.out.println(date);
}catch (Exception e){
e.printStackTrace();
}
}).start();
}
}
有线程会报错如下
可以synchronized
解决,但效率低
static void test2(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < 10; i++) {
new Thread(()->{
synchronized (dateFormat) {
try {
Date date = dateFormat.parse("1999-09-09");
System.out.println(date);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
DateTimeFormatter 线程安全
static void test3() {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
LocalDateTime dateTime = LocalDateTime.parse("2023-01-01 12:00:00", dateTimeFormatter);
System.out.println(dateTime);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
线程安全原理
首先DateTimeFormatter是个final class, 这样所有线程都能使用它,不会有线程安全问题
另外:java.time.format.DateTimeFormatter#parseResolved0,也是将输入的format字符串也修饰成final的
其它不可变设计模式例子
Java String类为什么是final的?
- value,offset和count这三个变量都是private的,并且没有提供setValue, setOffset和setCount等公共方法来修改这些值,所以在String类的外部无法修改String
- 为了实现字符串池
字符串池的实现可以在运行时节约很多heap
空间,因为不同的字符串变量都指向池中的同一个字符串。但如果字符串是可变的,那么String intern将不能实现,因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变
- 为了安全 & 线程安全
final不可变,确保线程安全
- 为了实现String可以创建HashCode不可变性,提高效率
因为字符串是不可变的,所以在它创建的时候HashCode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
但也要注意到问题: 对象会创建的比较多,即占用内存会多