關於 RequestContextHolder


RequestContextHolder

可以獲取當前的HttpServletRequest

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
        .getRequestAttributes()).getRequest();

實現原理 ThreadLocal

ThreadLocal是一個本地線程副本變量工具類。主要用於將私有線程和該線程存放的副本對象做一個映射,各個線程之間的變量互不干擾,在高並發場景下,可以實現無狀態的調用,特別適用於各個線程依賴不同的變量值完成操作的場景。

在每個線程的內部存在一個數據結構為Map的ThreadLocals變量,以<ThreadLocal,Value>的形式保存着線程變量和其對應的值。

對於不同的線程,每次獲取副本值時,別的線程並不能獲取到當前線程的副本值,形成了副本的隔離,互不干擾。

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);//當前線程為入參,獲取當前線程的threadLocals變量
        if (map != null)
         //入參為this,也就是說key為ThreadLocal對象
            map.set(this, value);
        else
            createMap(t, value);
    }

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);//當前線程為入參,獲取當前線程的threadLocals
        if (map != null) {
            //入參為this,也就是說key為ThreadLocal
            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;//threadLocals為線程的變量
    }
    
    private Entry getEntry(ThreadLocal<?> key) {
        int i = key.threadLocalHashCode & (table.length - 1);
        Entry e = table[i];
        if (e != null && e.get() == key)
            return e;
        else
            return getEntryAfterMiss(key, i, e);//避免內存泄漏,下文有提。
    }

Set():

  1. 獲取到當前線程的ThreadLocals ,類型為Map
  2. 將這個值放到這個Map的結構變量中,key為ThreadLocal對象,value為所存放的值。

Get():

  1. 獲取到當前線程的ThreadLocals
  2. 以ThreadLocal對象為Key獲取Value值

因為ThreadLocal對象作為Map的key ,所以一個ThreadLocal對象只能存放一個值,當存放多個時,會將新值覆蓋舊值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM