目录
先说原理:
再上代码:
运行结果:
先说原理:
ThreadLocal 是一个本地线程副本变量工具类,它可以在每个线程中创建一个副本变量,每个线程可以独立地修改自己的副本变量,而不会影响其他线程的副本变量。它的实现原理可以简单概括如下:
ThreadLocal内部维护了一个Map对象,用于存储每个线程的副本变量。Map的键为线程对象,值为对应线程的副本变量。- 在每个线程中,
ThreadLocal实例会创建一个唯一的ThreadLocalMap对象,用于存储该线程的所有副本变量。ThreadLocalMap是一个自定义的哈希表数据结构,继承自WeakReference,它的键为ThreadLocal对象,值为对应线程的副本变量。 - 在创建
ThreadLocal实例时,实际上是在当前线程的ThreadLocalMap中新增一个键值对,其中键为当前ThreadLocal对象,值为初始化的副本变量。 - 当需要获取当前线程的副本变量时,
ThreadLocal实例会先获取当前线程的ThreadLocalMap,再通过当前ThreadLocal对象作为键来获取对应的副本变量。由于每个线程独立维护自己的ThreadLocalMap,所以不同线程的相同ThreadLocal对象对应的副本变量也是不同的。 - 当一个线程结束时,它持有的所有
ThreadLocalMap中的键值对会成为垃圾对象,但由于ThreadLocalMap的键是WeakReference类型,所以这些键可能被垃圾回收器回收,但值对象不会被回收,从而导致内存泄漏。为了解决这个问题,ThreadLocal内部使用了ThreadLocalMap的expungeStaleEntry()方法,定期清除废弃的键值对。
总的来说,ThreadLocal 通过维护一个 Map,为每个线程创建一个独立的 ThreadLocalMap,并使用弱引用来避免内存泄漏,从而实现了在每个线程中创建独立的副本变量,并提供了线程安全的访问方式。
再上代码:
package cn.net.cdsz.ccb.test;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
public class test {
static class ThreadA implements Runnable {
private ThreadLocal<String> threadLocal;
public ThreadA(ThreadLocal<String> threadLocal) {
this.threadLocal = threadLocal;
}
@Override
public void run() {
threadLocal.set("A");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadA输出:" + threadLocal.get());
}
}
static class ThreadB implements Runnable {
private ThreadLocal<String> threadLocal;
public ThreadB(ThreadLocal<String> threadLocal) {
this.threadLocal = threadLocal;
}
@Override
public void run() {
threadLocal.set("B");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB输出:" + threadLocal.get());
}
}
public static void main(String[] args) {
ThreadLocal<String> threadLocal = new ThreadLocal<>();
new Thread(new ThreadA(threadLocal)).start();
new Thread(new ThreadB(threadLocal)).start();
}
}
运行结果:

最常⻅的ThreadLocal使⽤场景为⽤来解决数据库连接、Session管理等。数据库连
接和Session管理涉及多个复杂对象的初始化和关闭。如果在每个线程中声明⼀些
私有变量来进⾏操作,那这个线程就变得不那么“轻量”了,需要频繁的创建和关闭
连接。


















![用SSH登陆Centos系统时,命令行最前面显示“的提示符[root@www myapp]”是什么意思?](https://img-blog.csdnimg.cn/c7329cc0fe93428a958e324517873cf2.png)
