第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

ThreadLocal

求老仙 架構師
難度初級
時長 1小時40分
學習人數(shù)
綜合評分9.73
27人評價 查看評價
9.8 內(nèi)容實用
9.7 簡潔易懂
9.7 邏輯清晰
  • ThreadLocal源碼之回收HashMap空間

    remove操作,移除ThreadLocal實例中的數(shù)據(jù)并清理失效的數(shù)據(jù)

    /**
    ?*?Remove?the?entry?for?key.
    ?*/
    private?void?remove(ThreadLocal<?>?key)?{
    ????Entry[]?tab?=?table;
    ????int?len?=?tab.length;
    ????int?i?=?key.threadLocalHashCode?&?(len-1);
    ????for?(Entry?e?=?tab[i];
    ?????????e?!=?null;
    ?????????e?=?tab[i?=?nextIndex(i,?len)])?{
    ????????if?(e.get()?==?key)?{
    ????????????e.clear();
    ????????????expungeStaleEntry(i);
    ????????????return;
    ????????}
    ????}
    }
    /**
    ?*?Expunge?a?stale?entry?by?rehashing?any?possibly?colliding?entries
    ?*?lying?between?staleSlot?and?the?next?null?slot.??This?also?expunges
    ?*?any?other?stale?entries?encountered?before?the?trailing?null.??See
    ?*?Knuth,?Section?6.4
    ?*
    ?*?@param?staleSlot?index?of?slot?known?to?have?null?key
    ?*?@return?the?index?of?the?next?null?slot?after?staleSlot
    ?*?(all?between?staleSlot?and?this?slot?will?have?been?checked
    ?*?for?expunging).
    ?*/
    private?int?expungeStaleEntry(int?staleSlot)?{
    ????Entry[]?tab?=?table;
    ????int?len?=?tab.length;
    
    ????//?expunge?entry?at?staleSlot
    ????tab[staleSlot].value?=?null;
    ????tab[staleSlot]?=?null;
    ????size--;
    
    ????//?Rehash?until?we?encounter?null
    ????Entry?e;
    ????int?i;
    ????for?(i?=?nextIndex(staleSlot,?len);
    ?????????(e?=?tab[i])?!=?null;
    ?????????i?=?nextIndex(i,?len))?{
    ????????ThreadLocal<?>?k?=?e.get();
    ????????if?(k?==?null)?{
    ????????????e.value?=?null;
    ????????????tab[i]?=?null;
    ????????????size--;
    ????????}?else?{
    ????????????int?h?=?k.threadLocalHashCode?&?(len?-?1);
    ????????????if?(h?!=?i)?{
    ????????????????tab[i]?=?null;
    
    ????????????????//?Unlike?Knuth?6.4?Algorithm?R,?we?must?scan?until
    ????????????????//?null?because?multiple?entries?could?have?been?stale.
    ????????????????while?(tab[h]?!=?null)
    ????????????????????h?=?nextIndex(h,?len);
    ????????????????tab[h]?=?e;
    ????????????}
    ????????}
    ????}
    ????return?i;
    }


    查看全部
  • ThreadLocal源碼之模運算的不同寫法

    使用&進位來進行取模運算

    /**
    ?*?Construct?a?new?map?initially?containing?(firstKey,?firstValue).
    ?*?ThreadLocalMaps?are?constructed?lazily,?so?we?only?create
    ?*?one?when?we?have?at?least?one?entry?to?put?in?it.
    ?*/
    ThreadLocalMap(ThreadLocal<?>?firstKey,?Object?firstValue)?{
    ????table?=?new?Entry[INITIAL_CAPACITY];
    ????int?i?=?firstKey.threadLocalHashCode?&?(INITIAL_CAPACITY?-?1);
    ????table[i]?=?new?Entry(firstKey,?firstValue);
    ????size?=?1;
    ????setThreshold(INITIAL_CAPACITY);
    }


    查看全部
  • ThreadLocal源碼之自定義HashMap

    初始容量大小16

    /**
    ?*?The?initial?capacity?--?MUST?be?a?power?of?two.
    ?*/
    private?static?final?int?INITIAL_CAPACITY?=?16;

    擴容閾值容量空間的2/3

    /**
    ?*?The?next?size?value?at?which?to?resize.
    ?*/
    private?int?threshold;?//?Default?to?0
    
    /**
    ?*?Set?the?resize?threshold?to?maintain?at?worst?a?2/3?load?factor.
    ?*/
    private?void?setThreshold(int?len)?{
    ????threshold?=?len?*?2?/?3;
    }

    解決散列沖突的方式是尋找下一個存儲索引

    /**
    ?*?Set?the?value?associated?with?key.
    ?*
    ?*?@param?key?the?thread?local?object
    ?*?@param?value?the?value?to?be?set
    ?*/
    private?void?set(ThreadLocal<?>?key,?Object?value)?{
    
    ????//?We?don't?use?a?fast?path?as?with?get()?because?it?is?at
    ????//?least?as?common?to?use?set()?to?create?new?entries?as
    ????//?it?is?to?replace?existing?ones,?in?which?case,?a?fast
    ????//?path?would?fail?more?often?than?not.
    
    ????Entry[]?tab?=?table;
    ????int?len?=?tab.length;
    ????int?i?=?key.threadLocalHashCode?&?(len-1);
    
    ????for?(Entry?e?=?tab[i];
    ?????????e?!=?null;
    ?????????e?=?tab[i?=?nextIndex(i,?len)])?{
    ????????ThreadLocal<?>?k?=?e.get();
    
    ????????if?(k?==?key)?{
    ????????????e.value?=?value;
    ????????????return;
    ????????}
    
    ????????//?這里做判斷是由于k是WeakReference存儲的,有可能k已經(jīng)被GC回收了
    ????????if?(k?==?null)?{
    ????????????replaceStaleEntry(key,?value,?i);
    ????????????return;
    ????????}
    ????}
    
    ????tab[i]?=?new?Entry(key,?value);
    ????int?sz?=?++size;
    ????//?清理k被回收的槽并判斷是否需要擴容
    ????if?(!cleanSomeSlots(i,?sz)?&&?sz?>=?threshold)
    ????????rehash();
    }
    /**
    ?*?Increment?i?modulo?len.
    ?*/
    private?static?int?nextIndex(int?i,?int?len)?{
    ????return?((i?+?1?<?len)???i?+?1?:?0);
    }
    /**
    ?*?Replace?a?stale?entry?encountered?during?a?set?operation
    ?*?with?an?entry?for?the?specified?key.??The?value?passed?in
    ?*?the?value?parameter?is?stored?in?the?entry,?whether?or?not
    ?*?an?entry?already?exists?for?the?specified?key.
    ?*
    ?*?As?a?side?effect,?this?method?expunges?all?stale?entries?in?the
    ?*?"run"?containing?the?stale?entry.??(A?run?is?a?sequence?of?entries
    ?*?between?two?null?slots.)
    ?*
    ?*?@param??key?the?key
    ?*?@param??value?the?value?to?be?associated?with?key
    ?*?@param??staleSlot?index?of?the?first?stale?entry?encountered?while
    ?*?????????searching?for?key.
    ?*/
    private?void?replaceStaleEntry(ThreadLocal<?>?key,?Object?value,
    ???????????????????????????????int?staleSlot)?{
    ????Entry[]?tab?=?table;
    ????int?len?=?tab.length;
    ????Entry?e;
    
    ????//?Back?up?to?check?for?prior?stale?entry?in?current?run.
    ????//?We?clean?out?whole?runs?at?a?time?to?avoid?continual
    ????//?incremental?rehashing?due?to?garbage?collector?freeing
    ????//?up?refs?in?bunches?(i.e.,?whenever?the?collector?runs).
    ????int?slotToExpunge?=?staleSlot;
    ????for?(int?i?=?prevIndex(staleSlot,?len);
    ?????????(e?=?tab[i])?!=?null;
    ?????????i?=?prevIndex(i,?len))
    ????????if?(e.get()?==?null)
    ????????????slotToExpunge?=?i;
    
    ????//?Find?either?the?key?or?trailing?null?slot?of?run,?whichever
    ????//?occurs?first
    ????for?(int?i?=?nextIndex(staleSlot,?len);
    ?????????(e?=?tab[i])?!=?null;
    ?????????i?=?nextIndex(i,?len))?{
    ????????ThreadLocal<?>?k?=?e.get();
    
    ????????//?If?we?find?key,?then?we?need?to?swap?it
    ????????//?with?the?stale?entry?to?maintain?hash?table?order.
    ????????//?The?newly?stale?slot,?or?any?other?stale?slot
    ????????//?encountered?above?it,?can?then?be?sent?to?expungeStaleEntry
    ????????//?to?remove?or?rehash?all?of?the?other?entries?in?run.
    ????????if?(k?==?key)?{
    ????????????e.value?=?value;
    
    ????????????tab[i]?=?tab[staleSlot];
    ????????????tab[staleSlot]?=?e;
    
    ????????????//?Start?expunge?at?preceding?stale?entry?if?it?exists
    ????????????if?(slotToExpunge?==?staleSlot)
    ????????????????slotToExpunge?=?i;
    ????????????cleanSomeSlots(expungeStaleEntry(slotToExpunge),?len);
    ????????????return;
    ????????}
    
    ????????//?If?we?didn't?find?stale?entry?on?backward?scan,?the
    ????????//?first?stale?entry?seen?while?scanning?for?key?is?the
    ????????//?first?still?present?in?the?run.
    ????????if?(k?==?null?&&?slotToExpunge?==?staleSlot)
    ????????????slotToExpunge?=?i;
    ????}
    
    ????//?If?key?not?found,?put?new?entry?in?stale?slot
    ????tab[staleSlot].value?=?null;
    ????tab[staleSlot]?=?new?Entry(key,?value);
    
    ????//?If?there?are?any?other?stale?entries?in?run,?expunge?them
    ????if?(slotToExpunge?!=?staleSlot)
    ????????cleanSomeSlots(expungeStaleEntry(slotToExpunge),?len);
    }
    /**
    ?*?Heuristically?scan?some?cells?looking?for?stale?entries.
    ?*?This?is?invoked?when?either?a?new?element?is?added,?or
    ?*?another?stale?one?has?been?expunged.?It?performs?a
    ?*?logarithmic?number?of?scans,?as?a?balance?between?no
    ?*?scanning?(fast?but?retains?garbage)?and?a?number?of?scans
    ?*?proportional?to?number?of?elements,?that?would?find?all
    ?*?garbage?but?would?cause?some?insertions?to?take?O(n)?time.
    ?*
    ?*?@param?i?a?position?known?NOT?to?hold?a?stale?entry.?The
    ?*?scan?starts?at?the?element?after?i.
    ?*
    ?*?@param?n?scan?control:?{@code?log2(n)}?cells?are?scanned,
    ?*?unless?a?stale?entry?is?found,?in?which?case
    ?*?{@code?log2(table.length)-1}?additional?cells?are?scanned.
    ?*?When?called?from?insertions,?this?parameter?is?the?number
    ?*?of?elements,?but?when?from?replaceStaleEntry,?it?is?the
    ?*?table?length.?(Note:?all?this?could?be?changed?to?be?either
    ?*?more?or?less?aggressive?by?weighting?n?instead?of?just
    ?*?using?straight?log?n.?But?this?version?is?simple,?fast,?and
    ?*?seems?to?work?well.)
    ?*
    ?*?@return?true?if?any?stale?entries?have?been?removed.
    ?*/
    private?boolean?cleanSomeSlots(int?i,?int?n)?{
    ????boolean?removed?=?false;
    ????Entry[]?tab?=?table;
    ????int?len?=?tab.length;
    ????do?{
    ????????i?=?nextIndex(i,?len);
    ????????Entry?e?=?tab[i];
    ????????if?(e?!=?null?&&?e.get()?==?null)?{
    ????????????n?=?len;
    ????????????removed?=?true;
    ????????????i?=?expungeStaleEntry(i);
    ????????}
    ????}?while?(?(n?>>>=?1)?!=?0);
    ????return?removed;
    }
    /**
    ?*?Re-pack?and/or?re-size?the?table.?First?scan?the?entire
    ?*?table?removing?stale?entries.?If?this?doesn't?sufficiently
    ?*?shrink?the?size?of?the?table,?double?the?table?size.
    ?*/
    private?void?rehash()?{
    ????expungeStaleEntries();
    
    ????//?Use?lower?threshold?for?doubling?to?avoid?hysteresis
    ????if?(size?>=?threshold?-?threshold?/?4)
    ????????resize();
    }

    resize會擴容為原空間的2倍并重新散列數(shù)據(jù)

    /**
    ?*?Double?the?capacity?of?the?table.
    ?*/
    private?void?resize()?{
    ????Entry[]?oldTab?=?table;
    ????int?oldLen?=?oldTab.length;
    ????int?newLen?=?oldLen?*?2;
    ????Entry[]?newTab?=?new?Entry[newLen];
    ????int?count?=?0;
    
    ????for?(Entry?e?:?oldTab)?{
    ????????if?(e?!=?null)?{
    ????????????ThreadLocal<?>?k?=?e.get();
    ????????????if?(k?==?null)?{
    ????????????????e.value?=?null;?//?Help?the?GC
    ????????????}?else?{
    ????????????????int?h?=?k.threadLocalHashCode?&?(newLen?-?1);
    ????????????????while?(newTab[h]?!=?null)
    ????????????????????h?=?nextIndex(h,?newLen);
    ????????????????newTab[h]?=?e;
    ????????????????count++;
    ????????????}
    ????????}
    ????}
    
    ????setThreshold(newLen);
    ????size?=?count;
    ????table?=?newTab;
    }


    查看全部
  • ThreadLocal源碼之WeakReference

    /**
    ?*?The?entries?in?this?hash?map?extend?WeakReference,?using
    ?*?its?main?ref?field?as?the?key?(which?is?always?a
    ?*?ThreadLocal?object).??Note?that?null?keys?(i.e.?entry.get()
    ?*?==?null)?mean?that?the?key?is?no?longer?referenced,?so?the
    ?*?entry?can?be?expunged?from?table.??Such?entries?are?referred?to
    ?*?as?"stale?entries"?in?the?code?that?follows.
    ?*/
    static?class?Entry?extends?WeakReference<ThreadLocal<?>>?{
    ????/**?The?value?associated?with?this?ThreadLocal.?*/
    ????Object?value;
    
    ????Entry(ThreadLocal<?>?k,?Object?v)?{
    ????????super(k);
    ????????value?=?v;
    ????}
    }

    ThreadLocalMap.Entry 使用繼承 WeakReference 的方式實現(xiàn)并存儲ThreadLocal實例中的數(shù)據(jù),其目的是為了解決內(nèi)存回收的問題

    WeakReference不會計算其存儲對象的引用計數(shù),也就是說當該ThreadLocal實例不再被使用時,在程序執(zhí)行的某一刻Entry中存儲的ThreadLocal<?>引用可能會被GC回收掉

    查看全部
  • 帶著問題學源碼2

    查看全部
  • ThreadLocal源碼之哈希函數(shù)

    /**
    ?*?ThreadLocals?rely?on?per-thread?linear-probe?hash?maps?attached
    ?*?to?each?thread?(Thread.threadLocals?and
    ?*?inheritableThreadLocals).??The?ThreadLocal?objects?act?as?keys,
    ?*?searched?via?threadLocalHashCode.??This?is?a?custom?hash?code
    ?*?(useful?only?within?ThreadLocalMaps)?that?eliminates?collisions
    ?*?in?the?common?case?where?consecutively?constructed?ThreadLocals
    ?*?are?used?by?the?same?threads,?while?remaining?well-behaved?in
    ?*?less?common?cases.
    ?*/
    private?final?int?threadLocalHashCode?=?nextHashCode();
    
    /**
    ?*?The?next?hash?code?to?be?given?out.?Updated?atomically.?Starts?at
    ?*?zero.
    ?*/
    private?static?AtomicInteger?nextHashCode?=
    ????new?AtomicInteger();
    
    /**
    ?*?The?difference?between?successively?generated?hash?codes?-?turns
    ?*?implicit?sequential?thread-local?IDs?into?near-optimally?spread
    ?*?multiplicative?hash?values?for?power-of-two-sized?tables.
    ?*/
    private?static?final?int?HASH_INCREMENT?=?0x61c88647;
    
    /**
    ?*?Returns?the?next?hash?code.
    ?*/
    private?static?int?nextHashCode()?{
    ????return?nextHashCode.getAndAdd(HASH_INCREMENT);
    }


    查看全部
  • ThreadLocal源碼之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();
    ????ThreadLocalMap?map?=?getMap(t);
    ????if?(map?!=?null)?{
    ????????map.set(this,?value);
    ????}?else?{
    ????????createMap(t,?value);
    ????}
    }
    /**
    ?*?Create?the?map?associated?with?a?ThreadLocal.?Overridden?in
    ?*?InheritableThreadLocal.
    ?*
    ?*?@param?t?the?current?thread
    ?*?@param?firstValue?value?for?the?initial?entry?of?the?map
    ?*/
    void?createMap(Thread?t,?T?firstValue)?{
    ????t.threadLocals?=?new?ThreadLocalMap(this,?firstValue);
    }


    查看全部
  • ThreadLocal源碼之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)?{
    ????????????@SuppressWarnings("unchecked")
    ????????????T?result?=?(T)e.value;
    ????????????return?result;
    ????????}
    ????}
    ????return?setInitialValue();
    }
    /**
    ?*?Get?the?entry?associated?with?key.??This?method
    ?*?itself?handles?only?the?fast?path:?a?direct?hit?of?existing
    ?*?key.?It?otherwise?relays?to?getEntryAfterMiss.??This?is
    ?*?designed?to?maximize?performance?for?direct?hits,?in?part
    ?*?by?making?this?method?readily?inlinable.
    ?*
    ?*?@param??key?the?thread?local?object
    ?*?@return?the?entry?associated?with?key,?or?null?if?no?such
    ?*/
    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);
    }
    /**
    ?*?Variant?of?set()?to?establish?initialValue.?Used?instead
    ?*?of?set()?in?case?user?has?overridden?the?set()?method.
    ?*
    ?*?@return?the?initial?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);
    ????}
    ????if?(this?instanceof?TerminatingThreadLocal)?{
    ????????TerminatingThreadLocal.register((TerminatingThreadLocal<?>)?this);
    ????}
    ????return?value;
    }


    查看全部
  • 帶著問題學習源碼

    查看全部
  • 為什么ThreadLocal源碼中的getMap方法沒有使用Synchronize關鍵字修飾?

    MyThreadLocal中使用Synchronize方法是為了獲取threadLocalMap臨界區(qū),保證其是線程安全的。而在Thread源碼中維護了ThreadLocal.ThreadLocalMap,因此無需在ThreadLocal中維護ThreadLocalMap

    Thread 源碼

    /*?ThreadLocal?values?pertaining?to?this?thread.?This?map?is?maintained
    ?*?by?the?ThreadLocal?class.?*/
    ThreadLocal.ThreadLocalMap?threadLocals?=?null;

    ThreadLocal源碼

    /**
    ?*?Get?the?map?associated?with?a?ThreadLocal.?Overridden?in
    ?*?InheritableThreadLocal.
    ?*
    ?*?@param??t?the?current?thread
    ?*?@return?the?map
    ?*/
    ThreadLocalMap?getMap(Thread?t)?{
    ????return?t.threadLocals;
    }


    查看全部
    1. 可以引入鏈表解決哈希沖突,如果槽很大,則Map占用的內(nèi)存就越大,因此槽不是越大越好

    2. 能將數(shù)據(jù)散列的更分散的哈希函數(shù)更好

    3. 數(shù)據(jù)散列集中的危害是查詢數(shù)據(jù)時的時間復雜度比較高?

    查看全部
    0 采集 收起 來源:選學HashTable

    2020-02-17

  • 解決hash沖突

    查看全部
    0 采集 收起 來源:選學HashTable

    2020-02-17

  • thread local 源碼分析之 spring

    查看全部
  • thread local 源碼分析之 mybatis

    查看全部
  • thread local 源碼分析之 quartz

    查看全部

舉報

0/150
提交
取消
課程須知
1、對多線程、并發(fā)概念有一定了解 2、熟悉Java基本語法
老師告訴你能學到什么?
1、課程的主旨不是講死的概念,而是盡我所能的引發(fā)大家的思考,由現(xiàn)象觀察思考逐漸接近事物的本質(zhì)。 2、不僅理解ThreadLocal是什么?怎么用?何時用? 3、從設計者的角度去思考,大神們在怎么用,我應該怎樣用?——思考更多的為什么?為何而存在,為何要這樣設計。

微信掃碼,參與3人拼團

微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號

友情提示:

您好,此課程屬于遷移課程,您已購買該課程,無需重復購買,感謝您對慕課網(wǎng)的支持!