ThreadLocal原理

    xiaoxiao2025-10-11  14

    在学习消息机制的时候,了解到了ThreadLocal这个类,在这里分享给大家,希望对大家有所帮助。 首先我们来看一组代码: ThreadLocal<String> local1 = new ThreadLocal(); ThreadLocal<String> local2 = new ThreadLocal(); new Thread(){ @Override public void run() { local1.set("thread1"); Log.d("----thread1----" + local1.get()); Log.d("----thread1----" + local2.get()); } }.start(); new Thread(){ @Override public void run() { local2.set("thread2"); Log.d("----thread2----" + local1.get()); Log.d("----thread2----" + local2.get()); } }.start(); 运行结果:!(https://img-blog.csdn.net/20160815174829834) 我们可以发现在第一个线程中分明执行了local1.set(),也能通过local1.get()获取到刚刚设置的值,但是在第二个线程中local1.get()取值却为null呢? 带着这个疑问我们来看一下ThreadLocal的get和set方法 public void set(T value) { Thread currentThread = Thread.currentThread(); Values values = values(currentThread); if (values == null) { values = initializeValues(currentThread); } values.put(this, value); } 在外界调用set()之后,首先会通过values方法获取当前线程中的ThreadLocal的数据,数据存储在当前 线程的localValues中,如果localValues为null,就对其进行初始化,再将值进行存储。接下来我们来看看存 储 void put(ThreadLocal<?> key, Object value) { cleanUp(); // Keep track of first tombstone. That's where we want to go back // and add an entry if necessary. int firstTombstone = -1; for (int index = key.hash & mask;; index = next(index)) { Object k = table[index]; if (k == key.reference) { // Replace existing entry. table[index + 1] = value; return; } if (k == null) { if (firstTombstone == -1) { // Fill in null slot. table[index] = key.reference; table[index + 1] = value; size++; return; } // Go back and replace first tombstone. table[firstTombstone] = key.reference; table[firstTombstone + 1] = value; tombstones--; size++; return; } // Remember first tombstone. if (firstTombstone == -1 && k == TOMBSTONE) { firstTombstone = index; } } } 从这段代码中我们可以看出,key和value值在table数组中前后位的关系,注意这里是Values类中的方 法,也就是说对应的key、value值的存储是对对应线程localValues对象中table变量的操作。 接下来我们再来看一下get方法 public T get() { // Optimized for the fast path. Thread currentThread = Thread.currentThread(); Values values = values(currentThread); if (values != null) { Object[] table = values.table; int index = hash & values.mask; if (this.reference == table[index]) { return (T) table[index + 1]; } } else { values = initializeValues(currentThread); } return (T) values.getAfterMiss(this); } get方法逻辑很清晰,取当前Thread中的localValues对象,如果为null则返回初始值(默认初始值为 null),当然初始方法是可以重写的,不为空则取出table找到对应ThreadLocal的value。 候,比如Looper。 个人觉得ThreadLocal类也为我们在解决实际问题中提供了一种思路,不以ThreadLocal为数据存储容器 而是以不同的作用域为存储容器,使用复杂度、项目耦合度都有所改善 有问题欢迎指正=。=
    转载请注明原文地址: https://ju.6miu.com/read-1303037.html
    最新回复(0)