可能现在一提到线程大家就都想拿线程与进程作比较,那么你真的了解线程吗?知道ThreadLocal原理是什么吗?明确过ThreadLocal的使用场景有哪些吗?有兴趣了解的小伙伴可以跟小编一起来看看哦。
实现我们来看看,什么是ThreadLocal变量。
ThreadLoal 变量,即线程局部变量,同一个 ThreadLocal 所包含的对象,在不同的 Thread 里面会有不同的副本。这里呢有几点需要注意一下:
因为每个 Thread 里面都有自己的实例副本,而且该副本只能由当前 Thread 使用。这是其实也是 ThreadLocal 命名的由来。
那既然每个 Thread 有自己的实例副本,然后 Thread 不可访问,那就不存在多线程间共享的问题啦。
ThreadLocal 提供了线程本地的实例。它与普通变量的区别在于每个使用该变量的线程,都会去初始化一个完全独立的实例副本。ThreadLocal 变量通常会被private static修饰。每当一个线程结束的时候,它所使用的所有 ThreadLocal 相对的实例副本都可被回收。
其实总的来说,ThreadLocal适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景。
ThreadLocal实现原理如下:
首先 ThreadLocal 是一个泛型类,保证是可以接受任何类型的对象的。
因为一个线程内可以存在多个 ThreadLocal对象,所以其实就是ThreadLocal内部维护了一个Map ,这个Map不是直接使用的HashMap,而是ThreadLocal实现的一个叫做ThreadLocalMap 的静态内部类。而我们使用的get()、set()方法其实都是调用了这个ThreadLocalMap类对应的 get()、set() 方法。例如下面的 set 方法:
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
get方法:
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) return (T) map.get(this); // Maps are constructed lazily. if the map for this thread // doesn't exist, create it, with this ThreadLocal and its // initial value as its only entry. T value = initialValue(); createMap(t, value); return value; }
createMap方法:
void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } ThreadLocalMap是个静态的内部类: static class ThreadLocalMap { ........ }
最终的变量是放在了当前线程的 ThreadLocalMap 中,并不是存在 ThreadLocal 上,ThreadLocal 可以理解为只是ThreadLocalMap的封装,传递了变量值。
那么如上文所述呢,ThreadLocal 适用于如下两种场景:
每个线程需要有自己单独的实例;
实例需要在多个方法中共享,但不希望被多线程共享。
对于第一点来说,每个线程拥有自己实例,实现它的方式有很多。例如可以在线程内部构建一个单独的实例。ThreadLoca可以以非常方便的形式满足该需求。
对于第二点,可以在满足第一点(每个线程有自己的实例)的条件下,通过方法间引用传递的形式实现。ThreadLocal使得代码耦合度更低,且实现更优雅。
以上就是有关ThreadLocal原理的所有内容了,还想了解更多java常见问答相关信息的话,欢迎来关注本站最新消息哦。
推荐阅读: