美文网首页
java基础之ThreadLoacl

java基础之ThreadLoacl

作者: 暴走的小青春 | 来源:发表于2019-07-27 15:06 被阅读0次

    相信很多人都会threadloacl有着自己的理解,android 里也到处有threadloacl的影子
    比如:

    public final class Looper {
        
    
        private static final String TAG = "Looper";
    
        // sThreadLocal.get() will return null unless you've called prepare().
        static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
        private static Looper sMainLooper;  // guarded by Looper.class
    ...
    
    }
    

    还有otto的bus中

    public class Bus {
     
      public static final String DEFAULT_IDENTIFIER = "default";
     
      /** All registered event handlers, indexed by event type. */
      private final ConcurrentMap<Class<?>, Set<EventHandler>> handlersByType =
              new ConcurrentHashMap<Class<?>, Set<EventHandler>>();
     
      /** All registered event producers, index by event type. */
      private final ConcurrentMap<Class<?>, EventProducer> producersByType =
              new ConcurrentHashMap<Class<?>, EventProducer>();
     
      /** Identifier used to differentiate the event bus instance. */
      private final String identifier;
     
      /** Thread enforcer for register, unregister, and posting events. */
      private final ThreadEnforcer enforcer;
     
      /** Used to find handler methods in register and unregister. */
      private final HandlerFinder handlerFinder;
     
      /** Queues of events for the current thread to dispatch. */
      private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>> eventsToDispatch =
          new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
            @Override protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
              return new ConcurrentLinkedQueue<EventWithHandler>();
            }
          };
    

    都有其身影,有的还在定义时候重载了initialValue这个方法,那现在一探究竟,看看其原理所在
    首先看其get方法

       public T get() {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null) {
                ThreadLocalMap.Entry e = map.getEntry(this);
                if (e != null) {
                    @SuppressWarnings("unchecked")
                    T result = (T)e.value;
                    return result;
                }
            }
            return setInitialValue();
        }
    
        ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    

    可以说先取出当前线程,然后把当前线程找到这个thread类的成员变量 ThreadLocalMap看其是否为null,如果不为空,就用此threadloacl对象作为key去找寻其value如果为空

       private T setInitialValue() {
            T value = initialValue();
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
            return value;
        }
    

    就调用待复写的initialValue方法
    在查看这个线程对应的ThreadLocalMap,如果有就set,没有就新建
    举个例子:
    a,b,c类在住线程定义了threadlocal对象,那么这个map的健就是三个threadlocal对象,值就是threadloacl里的值,因为他的map和当前的thread是紧密关联的

    在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);
        }
    

    所以只要这个对象被放进不同的threadloacl里,比如是一个list:你在主线程add数据,那你在其他线程get是拿不到的,这也就是otto会把ConcurrentLinkedQueue<EventWithHandler>放进threadlocal的原理所在!

    相关文章

      网友评论

          本文标题:java基础之ThreadLoacl

          本文链接:https://www.haomeiwen.com/subject/zpcerctx.html