ThreadLocal简介:
变量值的共享可以使用public static的形式,使所有线程都使用同一个变量;如果想实现每一个线程都有自己的共享变量该如何实现呢?JDK中的ThreadLocal类正是为了解决这样的问题。
ThreadLocal类并不是用来解决多线程环境下的共享变量问题,而是用来提供线程内部的共享变量,在多线程环境下,可以保证各个线程之间的变量互相隔离、相互独立。在线程中,可以通过get()/set()方法来访问变量。ThreadLocal实例通常来说都是private static类型的,它们希望将状态与线程进行关联。这种变量在线程的生命周期内起作用,可以减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。
代码案例:
/**
* Java并发编程之ThreadLocal
* @author 尘世间迷途的小书童
*
*/
public class ThreadLocalTest extends Thread {
private static ThreadLocal<Integer> flag = new ThreadLocal<Integer>();
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(int i=0; i<10; i++) {
if("B".equals(getName())) {
flag.set(100);
}else {
flag.set(i);
}
System.out.println(getName() + " threadLocal.get()= " + flag.get());
}
}
public static void main(String[] args) {
Thread threadA = new ThreadLocalTest();
threadA.setName("A");
Thread threadB = new ThreadLocalTest();
threadB.setName("B");
Thread threadC = new ThreadLocalTest();
threadC.setName("C");
threadA.start();
threadB.start();
threadC.start();
}
}
A threadLocal.get()= 0
B threadLocal.get()= 100
C threadLocal.get()= 0
B threadLocal.get()= 100
A threadLocal.get()= 1
B threadLocal.get()= 100
C threadLocal.get()= 1
B threadLocal.get()= 100
A threadLocal.get()= 2
B threadLocal.get()= 100
C threadLocal.get()= 2
B threadLocal.get()= 100
A threadLocal.get()= 3
B threadLocal.get()= 100
C threadLocal.get()= 3
B threadLocal.get()= 100
A threadLocal.get()= 4
B threadLocal.get()= 100
C threadLocal.get()= 4
B threadLocal.get()= 100
A threadLocal.get()= 5
C threadLocal.get()= 5
A threadLocal.get()= 6
C threadLocal.get()= 6
A threadLocal.get()= 7
C threadLocal.get()= 7
A threadLocal.get()= 8
C threadLocal.get()= 8
A threadLocal.get()= 9
C threadLocal.get()= 9
虽然两个线程都在向threadLocal对象中set()数据值,但每个线程都还是能取出自己设置的数据,确实可以达到隔离线程变量的效果。
ThreadLocal源码解析:
ThreadLocal常用方法介绍:
get()方法:获取与当前线程关联的ThreadLocal值。
set(T value)方法:设置与当前线程关联的ThreadLocal值。
initialValue()方法:设置与当前线程关联的ThreadLocal初始值。
当调用get()方法的时候,若是与当前线程关联的ThreadLocal值已经被设置过,则不会调用initialValue()方法;否则,会调用initialValue()方法来进行初始值的设置。通常initialValue()方法只会被调用一次,除非调用了remove()方法之后又调用get()方法,此时,与当前线程关联的ThreadLocal值处于没有设置过的状态(其状态体现在源码中,就是线程的ThreadLocalMap对象是否为null),initialValue()方法仍会被调用。
remove()方法:将与当前线程关联的ThreadLocal值删除。
实现原理:
研究中。。。
推荐阅读: https://blog.csdn.net/qq_38293564/article/details/80459827