下面是一个使用ThreadLocal的简单案例:
假设有一个计数器类CountingThreadLocal,它使用ThreadLocal保存计数器的值。在主线程中创建多个子线程,每个子线程都从主线程读取数据,修改计数器的值,设置到自己的本地内存里面,并打印结果。
一张示意图如下:
代码实现如下:
public class CountingThreadLocal { private static final ThreadLocal<Integer> counter = new ThreadLocal<Integer>(){ @Override protected Integer initialValue() { return 0; } }; public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { int count = counter.get(); // 获取当前线程的计数器值 count++; // 修改计数器值 System.out.println("Thread " + Thread.currentThread().getName() + " counts: " + count); counter.set(count); // 将修改后的计数器值保存回ThreadLocal中 }).start(); } } }
输出结果如下:
Thread Thread-0 counts: 1 Thread Thread-4 counts: 1 Thread Thread-3 counts: 1 Thread Thread-2 counts: 1 Thread Thread-1 counts: 1 Thread Thread-7 counts: 1 Thread Thread-6 counts: 1 Thread Thread-5 counts: 1 Thread Thread-9 counts: 1 Thread Thread-8 counts: 1
在上述代码中,我们使用ThreadLocal保存了一个Integer类型的计数器值。在主线程中创建多个子线程时,每个子线程都会获取当前线程的计数器值并进行修改。由于使用了ThreadLocal机制,每个线程都有自己的计数器副本,因此不会受到其他线程的影响。最终输出的结果将展示每个线程的计数器值。
最后我们总结一下:
- ThreadLocal的实现涉及到三个类:ThreadLocal、ThreadLocalMap和WeakReference。
- ThreadLocal是一种非常有用的线程局部变量存储机制,它允许每个线程拥有自己的数据副本,从而避免了数据竞争和线程之间的干扰。