final变量
fina指read-only的意思,很容易理解
简单入门
class Student {
final String name
Student(String name) {
this.name = name
}
}
Student student = new Student("smith")
// 报错
student.name = "changed"
为什么String是final的
String通过final class 与 final array表示String即无法继承,也无法修改,让String在语义上保证不可变性
ThreadLocal
ThreadLocal是线程本地独有可见的变量(各管各的),一般用于上下文管理
简单入门
举个常见的反序列化例子
private static ThreadLocal<SimpleDateFormat> f = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
原理
threadLocal看起来像是在“栈”上,实际上它还是Thread的成员变量,还是在堆上的,每次实际上通过访问如下获得
//类型如下
//Thread
//ThreadLocal.ThreadLocalMap
//ThreadLocal.ThreadLocalMap.Entry[]
//T
Thread.currentThread().threadLocals.table[i].value
其中
- i: 通过ThreadLocal的全局成员变量nextHashCode进行自增,每多一个ThreadLocal实例,自增一次
- value: 通过initialValue传入的对象
在企业开发中的作用
ThreadLocal是线程本地独有可见的变量,一般用于上下文管理
比如
- 管理Spring-transaction: 数据库事务
- 管理BPM流程上下文: 这个主要是在企业级应用中使用,自己跳自己的伞,一个线程走到底
- 业务路由: Tomcat中的
getRequestDispatcher
进行重定向,比如资源静态化的Filter
在序列化的作用
在进行序列化与反序列化时,内部一定会通过一个状态机来维护上下文,如果它不是线程安全的,那么状态机一定会出问题
- SimpleDataFormat.parse(不是线程安全)
- BigDecimal.toString(线程安全)
- String
.<init>
(线程安全)