ThreadLocal
- 什么是 ThreadLocal ?
ThreadLocal 提高一个线程的局部变量,访问某个线程拥有自己局部变量。 当使用 ThreadLocal 维护变量时,ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 ThreadLocal 的接口方法 ThreadLocal 类接口很简单,只有 4 个方法,我们先来了解一下:
1、void set(Object value)设置当前线程的线程局部变量的值。
2、public Object get()该方法返回当前线程所对应的线程局部变量。
3、public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方 法是 JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存 回收的速度。
4、protected Object initialValue()返回该线程局部变量的初始值,该方法是一个 protected 的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第 1 次调用 get()或set(Object)时才执行,并且仅执行 1 次。ThreadLocal 中的缺省实现直接返回一个 null。
例子
- 创建三个线程,每个线程生成自己独立序列号。
/**
* @Author : PengPeng
*/
public class Thread02 {
public static void main(String[] args) {
Res res = new Res();
Thread t1 = new Thread002(res);
Thread t2 = new Thread002(res);
Thread t3 = new Thread002(res);
t1.start();
t2.start();
t3.start();
}
}
class Thread002 extends Thread{
private Res res;
public Thread002(Res res){
this.res = res;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("当前线程:" + Thread.currentThread() + "== " + i + " ==" + res.getIll());
}
}
}
class Res{
public static Integer ill = 0;
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return 0;
}
};
public Integer getIll(){
Integer temp = threadLocal.get() + 1;
threadLocal.set(temp);
return temp;
}
}
- 执行结果
当前线程:Thread[Thread-2,5,main]== 0 ==1
当前线程:Thread[Thread-0,5,main]== 0 ==1
当前线程:Thread[Thread-0,5,main]== 1 ==2
当前线程:Thread[Thread-1,5,main]== 0 ==1
当前线程:Thread[Thread-0,5,main]== 2 ==3
当前线程:Thread[Thread-2,5,main]== 1 ==2
当前线程:Thread[Thread-1,5,main]== 1 ==2
当前线程:Thread[Thread-2,5,main]== 2 ==3
当前线程:Thread[Thread-1,5,main]== 2 ==3
Process finished with exit code 0
实现原理
ThreadLocal 通过 map 集合 Map.put(“当前线程”, 值);