1. ThreadLocal概述
1.ThreadLocal提供线程局部变量;开箱即用开销小,可以代替多线程访问共享变量时需要上锁的需要。
在各种涉及的多线程语言都有,Java用哈希表表实现(ThreadLocalMap)
3.实现原理
2. 基本API
1.构造函数ThreadLocal()
2.初始化 initialValue()
只有线程在第一次调用get方法时,执行此方法。
3.访问器 get/set
public T get(),返回ThreadLocal中当前线程副本的值。变量第一次get时没有当前线程的值,就调用initilaVaule()的返回值。
4.回收 remove
以下手动来个demo(涉及到延迟加载)
//用泛型构造器赋初始值
public static ThreadLocal<Long> x = new ThreadLocal<>(){
@Override
protected Long initialValue() {
System.out.println("Initial Value run...");
return Thread.currentThread().getId(); //拿到当前线程ID
}
};
public static void main(String[] argv){
new Thread(){
@Override
public void run(){
System.out.println(x.get());
}
}.start();
System.out.println(x.get());
}
}
结果是:(main函数中两个不同get都各调用了一次InitialValue方法,每个线程都有自己的变量值)
下面是测试set方法:
public class APItests {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>(){
@Override
protected Long initialValue() {
System.out.println("Initial Value run...");
return Thread.currentThread().getId();
}
};
public static void main(String[] argv) {
new Thread() {
@Override
public void run() {
System.out.println(threadLocal.get());
}
}.start();
threadLocal.set(6l);
System.out.println(threadLocal.get());
}
}
得到的结果如下:可见InitialValue只调用了一次
3. ThreadLocal使用场景
- 1.线程安全
- 2.线程资源一致
基于线程池模型去Sychronized很危险:排队去锁消耗的时间导致CPU用不完
eg:线程池中24个线程,打来100个并发量,一次只能24个,而用ThreadLocal收集数据很快且安全。
同一个事务下的任务们必须保证原子性,也就是说下图中的Task们都须通过同一个线程的getConnection()方法拿到完全相同的数据。首先判断ThreadLocalMap中是否存在所需值,如果没有就去连接池取,取到的值先存到线程共享的ThreadLocalMap中,再返回给对应Task。
(3)并发计算
常见于分布式计算,一台机器多核并行
扫描二维码关注公众号,回复:
11229498 查看本文章