ThreadLocal 线程独立的数据
-
线程拥有自己的数据,使用自己的局部变量比使用全局变量好
-
局部变量只有线程自己可见,不会影响其他线程
-
ThreadLocal能放一个线程级别的变量,其本身能被多个线程共享使用(可共享给子线程),并且能达到线程安全的目的
-
常用方法 get / set / initialValue
-
建议将ThreadLocal定义为private static
-
hreadLocal最常用于为每个线程绑定一个数据库连接、http请求、用户身份信息等,这样一个线程所有调用到的方法都可以非常方便地访问这些资源
- Hibernate的Session,工具类HibernateUtil
- 通过不同的线程对象设置Bean属性,保证各个线程Bean对象的独立性
package com.tsymq.thread.advanced;
public class ThreadLocalTest {
private static User user = new User(101, "ts");
// 默认
// private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
// 重写 更改初始化值
/*private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>(){
@Override
protected Integer initialValue() {
return 200;
}
};*/
// lambda表达式方式
private static ThreadLocal<Object> threadLocal = ThreadLocal.withInitial( () -> user);
public static void main(String[] args) {
// 主线程
// 获取
System.out.println(Thread.currentThread().getName() + "<-->" + threadLocal.get());
// 更改
threadLocal.set(99);
System.out.println(Thread.currentThread().getName() + "<-->" + threadLocal.get());
// 另一个线程
new Thread(new MyTL()).start();
}
}
class User{
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
class MyTL implements Runnable{
private static User user = new User(102, "ymq");
// private static ThreadLocal<Object> threadLocal = ThreadLocal.withInitial( () -> user);
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ "<-->"
+ ThreadLocal.withInitial(()->user).get());
}
}