<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # Java線程(篇外篇):線程本地變量ThreadLocal 首先說明ThreadLocal存放的值是線程內共享的,線程間互斥的,主要用于線程內共享一些數據,避免通過參數來傳遞,這樣處理后,能夠優雅的解決一些實際問題,比如Hibernate中的OpenSessionInView,就是使用ThreadLocal保存Session對象,還有我們經常用ThreadLocal存放Connection,代碼如: ~~~ /**? ?*?數據庫連接管理類? ?*?@author?爽? ?*? ?*/?? public?class?ConnectionManager?{?? ?? ????/**?線程內共享Connection,ThreadLocal通常是全局的,支持泛型?*/?? ????private?static?ThreadLocal?threadLocal?=?new?ThreadLocal();?? ?????? ????public?static?Connection?getCurrConnection()?{?? ????????//?獲取當前線程內共享的Connection?? ????????Connection?conn?=?threadLocal.get();?? ????????try?{?? ????????????//?判斷連接是否可用?? ????????????if(conn?==?null?||?conn.isClosed())?{?? ????????????????//?創建新的Connection賦值給conn(略)?? ????????????????//?保存Connection?? ????????????????threadLocal.set(conn);?? ????????????}?? ????????}?catch?(SQLException?e)?{?? ????????????//?異常處理?? ????????}?? ????????return?conn;?? ????}?? ?????? ????/**? ?????*?關閉當前數據庫連接? ?????*/?? ????public?static?void?close()?{?? ????????//?獲取當前線程內共享的Connection?? ????????Connection?conn?=?threadLocal.get();?? ????????try?{?? ????????????//?判斷是否已經關閉?? ????????????if(conn?!=?null?&&?!conn.isClosed())?{?? ????????????????//?關閉資源?? ????????????????conn.close();?? ????????????????//?移除Connection?? ????????????????threadLocal.remove();?? ????????????????conn?=?null;?? ????????????}?? ????????}?catch?(SQLException?e)?{?? ????????????//?異常處理?? ????????}?? ????}?? }?? ~~~ 這樣處理的好處: 1. 統一管理Connection; 2. 不需要顯示傳參Connection,代碼更優雅; 3. 降低耦合性。 ThreadLocal有四個方法,分別為: ### initialValue ~~~ protected T initialValue() ~~~ 返回此線程局部變量的當前線程的初始值。最多在每次訪問線程來獲得每個線程局部變量時調用此方法一次,即線程第一次使用?[`get()`](http://blog.csdn.net/ghsau/article/details/15732053)?方法訪問變量的時候。如果線程先于?get?方法調用?[`set(T)`](http://blog.csdn.net/ghsau/article/details/15732053)?方法,則不會在線程中再調用?initialValue?方法。 該實現只返回?null;如果程序員希望將線程局部變量初始化為?null?以外的某個值,則必須為?ThreadLocal?創建子類,并重寫此方法。通常,將使用匿名內部類。initialValue?的典型實現將調用一個適當的構造方法,并返回新構造的對象。 **返回:** 返回此線程局部變量的初始值 * * * ### get ~~~ public T get() ~~~ 返回此線程局部變量的當前線程副本中的值。如果這是線程第一次調用該方法,則創建并初始化此副本。 **返回:** 此線程局部變量的當前線程的值 * * * ### set ~~~ public void set(T?value) ~~~ 將此線程局部變量的當前線程副本中的值設置為指定值。許多應用程序不需要這項功能,它們只依賴于?[`initialValue()`](http://blog.csdn.net/ghsau/article/details/15732053)?方法來設置線程局部變量的值。 **參數:** `value`?- 存儲在此線程局部變量的當前線程副本中的值。 * * * ### remove ~~~ public void remove() ~~~ 移除此線程局部變量的值。這可能有助于減少線程局部變量的存儲需求。如果再次訪問此線程局部變量,那么在默認情況下它將擁有其initialValue。 很多人對ThreadLocal存在一定的誤解,說ThreadLocal中有一個全局的Map,set時執行map.put(Thread.currentThread(), value),get和remove時也同理,但SUN的大師們是否是如此實現的,我們只能去看源碼了。 set方法: ~~~ /**? ?*?Sets?the?current?thread's?copy?of?this?thread-local?variable? ?*?to?the?specified?value.??Most?subclasses?will?have?no?need?to? ?*?override?this?method,?relying?solely?on?the?{@link?#initialValue}? ?*?method?to?set?the?values?of?thread-locals.? ?*? ?*?@param?value?the?value?to?be?stored?in?the?current?thread's?copy?of? ?*????????this?thread-local.? ?*/?? public?void?set(T?value)?{?? ????//?獲取當前線程對象?? ????Thread?t?=?Thread.currentThread();?? ????//?獲取當前線程本地變量Map?? ????ThreadLocalMap?map?=?getMap(t);?? ????//?map不為空?? ????if?(map?!=?null)?? ????????//?存值?? ????????map.set(this,?value);?? ????else?? ????????//?創建一個當前線程本地變量Map?? ????????createMap(t,?value);?? }?? ?? /**? ?*?Get?the?map?associated?with?a?ThreadLocal.?Overridden?in? ?*?InheritableThreadLocal.? ?*? ?*?@param??t?the?current?thread? ?*?@return?the?map? ?*/?? ThreadLocalMap?getMap(Thread?t)?{?? ????//?獲取當前線程的本地變量Map?? ????return?t.threadLocals;?? }?? ~~~ 這里注意,ThreadLocal中是有一個Map,但這個Map不是我們平時使用的Map,而是ThreadLocalMap,ThreadLocalMap是ThreadLocal的一個內部類,不對外使用的。當使用ThreadLocal存值時,首先是獲取到當前線程對象,然后獲取到當前線程本地變量Map,最后將當前使用的ThreadLocal和傳入的值放到Map中,也就是說ThreadLocalMap中存的值是[ThreadLocal對象, 存放的值],這樣做的好處是,每個線程都對應一個本地變量的Map,所以**一個線程可以存在多個線程本地變量**。 get方法: ~~~ /**? ?*?Returns?the?value?in?the?current?thread's?copy?of?this? ?*?thread-local?variable.??If?the?variable?has?no?value?for?the? ?*?current?thread,?it?is?first?initialized?to?the?value?returned? ?*?by?an?invocation?of?the?{@link?#initialValue}?method.? ?*? ?*?@return?the?current?thread's?value?of?this?thread-local? ?*/?? public?T?get()?{?? ????Thread?t?=?Thread.currentThread();?? ????ThreadLocalMap?map?=?getMap(t);?? ????if?(map?!=?null)?{?? ????????ThreadLocalMap.Entry?e?=?map.getEntry(this);?? ????????if?(e?!=?null)?? ????????????return?(T)e.value;?? ????}?? ????//?如果值為空,則返回初始值?? ????return?setInitialValue();?? }?? ~~~ 有了之前set方法的分析,get方法也同理,需要說明的是,如果沒有進行過set操作,那從ThreadLocalMap中拿到的值就是null,這時get方法會返回初始值,也就是調用initialValue()方法,ThreadLocal中這個方法默認返回null。當我們有需要第一次get時就能得到一個值時,可以繼承ThreadLocal,并且覆蓋initialValue()方法。 ? ? ? ?(完)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看