中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站上的地圖怎么做小程序開發(fā)教程全集免費(fèi)

網(wǎng)站上的地圖怎么做,小程序開發(fā)教程全集免費(fèi),如何操作網(wǎng)站建設(shè)團(tuán)隊(duì)是什么,白塔網(wǎng)站建設(shè)文章目錄 exampleset(T value)createMap(t, value);set(ThreadLocal<?> key, Object value)ThreadLocalMap和Thread的關(guān)系 全貌 ThreadLocal是個(gè)很重要的多線程類&#xff0c;里面數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)很有意思&#xff0c;很巧妙。但是我們平時(shí)使用它的時(shí)候常常容易對它的使用…

文章目錄

  • example
  • set(T value)
    • createMap(t, value);
    • set(ThreadLocal<?> key, Object value)
    • ThreadLocalMap和Thread的關(guān)系
  • 全貌

ThreadLocal是個(gè)很重要的多線程類,里面數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)很有意思,很巧妙。但是我們平時(shí)使用它的時(shí)候常常容易對它的使用感到迷惑,因?yàn)樗渌腁PI很不一樣,使用很不一樣,設(shè)計(jì)也很不一樣。

但是不用擔(dān)心,這篇文章將從源碼出發(fā),一步步深入剖析ThreadLocal內(nèi)部構(gòu)造,理清楚它的來龍去脈。

example

還是從一個(gè)使用用例出發(fā):

public class ThreadLocalExample {// 聲明一個(gè) ThreadLocal 變量private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();public static void main(String[] args) {// 在主線程中設(shè)置變量值threadLocal.set(10);// 創(chuàng)建并啟動(dòng)一個(gè)新線程Thread thread = new Thread(() -> {// 在新線程中獲取變量值System.out.println("ThreadLocal value in new thread: " + threadLocal.get());});thread.start();// 在主線程中獲取變量值System.out.println("ThreadLocal value in main thread: " + threadLocal.get());}
}

打印結(jié)果:

ThreadLocal value in main thread: 10
ThreadLocal value in new thread: null

可以看出同一個(gè)threadLocal 對象,在不同的線程里面調(diào)用get方法,獲取的是不一樣的結(jié)果!也就是說,threadLocal 對象存儲(chǔ)了不同線程的私有變量。

現(xiàn)在可能我們還是覺得云里霧里,那現(xiàn)在我們就從源碼出發(fā),來一步步進(jìn)行分析。

從threadLocal.set(10);方法進(jìn)去:

set(T value)

    /*** 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);elsecreateMap(t, value);}

創(chuàng)建map或者設(shè)置key&value。

createMap(t, value);

先來看看假如map==null它怎么做:

    /*** 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);}

這里把new出來的ThreadLocalMap賦值給了t.threadLocals,t是個(gè)線程。

        /*** 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);}

這里是ThreadLocalMap的構(gòu)造方法,可以看出ThreadLocal作為key,傳進(jìn)來的參數(shù)作為value。

set(ThreadLocal<?> key, Object value)

現(xiàn)在回退一下,看看map.set(this, value);做了什么:

        /*** 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;}if (k == null) {replaceStaleEntry(key, value, i);return;}}tab[i] = new Entry(key, value);int sz = ++size;if (!cleanSomeSlots(i, sz) && sz >= threshold)rehash();}

這里有必要知道的是該方法位于ThreadLocalMap類里面:
在這里插入圖片描述
看下Entry 的實(shí)現(xiàn)代碼:

        /*** 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;}}

Entry 是個(gè)弱引用的子類。設(shè)計(jì)為弱引用,說明它跟內(nèi)存泄漏有關(guān)。這里先不深入探討。

到這里我們可以得知set方法執(zhí)行的時(shí)候以ThreadLocal對象作為key,以value入?yún)⒆鳛関alue,傳到了ThreadLocal的 Entry[] 里面,設(shè)置的時(shí)候根據(jù)threadLocal對象的hash值來確定其在ThreadLocalMap中的位置。

ThreadLocalMap和Thread的關(guān)系

還記得前面的這行代碼嗎?

 t.threadLocals = new ThreadLocalMap(this, firstValue);

createMap(t, value);里面,來看看ThreadLocalMap和Thread的關(guān)系:

java/lang/Thread.java

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

也就是說ThreadLocalMap 其實(shí)是屬于線程的成員變量。

全貌

其實(shí)到這里,我們已經(jīng)有能力知道整體的數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)了,下面我們通過前面給出的example代碼,通過畫圖的方式把它們之間關(guān)系全貌繪制出來:

在這里插入圖片描述

ThreadLocalMap里面是Entry數(shù)組,那么其它Entry元素怎么用呢?
這是個(gè)好問題,我們迭代下前面的example:

class ThreadLocalExample {// 聲明一個(gè) ThreadLocal 變量private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();private static ThreadLocal<String> threadLocal2 = new ThreadLocal<>();public static void main(String[] args) {// 在主線程中設(shè)置變量值threadLocal.set(10);threadLocal2.set("hello");// 創(chuàng)建并啟動(dòng)一個(gè)新線程Thread thread = new Thread(() -> {// 在新線程中獲取變量值System.out.println("ThreadLocal value in new thread: " + threadLocal.get());System.out.println("ThreadLocal2 value in new thread: " + threadLocal2.get());});thread.start();// 在主線程中獲取變量值System.out.println("ThreadLocal value in main thread: " + threadLocal.get());System.out.println("ThreadLocal2 value in main thread: " + threadLocal2.get());}
}

運(yùn)行結(jié)果:

ThreadLocal value in main thread: 10
ThreadLocal value in new thread: null
ThreadLocal2 value in main thread: hello
ThreadLocal2 value in new thread: null

再來一個(gè)圖:
在這里插入圖片描述
一圖勝千言,到這里我們應(yīng)該對ThreadLocal這個(gè)線程類的整體有個(gè)清晰的把握了。

enjoy it。

http://www.risenshineclean.com/news/60523.html

相關(guān)文章:

  • 做網(wǎng)站是互聯(lián)網(wǎng)開發(fā)嗎網(wǎng)站權(quán)重怎么看
  • 網(wǎng)站怎么寫容易獲得關(guān)鍵詞排名杭州seo代理公司
  • 網(wǎng)站為什么做等保網(wǎng)站優(yōu)化塔山雙喜
  • java 網(wǎng)站開發(fā)實(shí)例教程網(wǎng)絡(luò)推廣的基本渠道
  • 濟(jì)南微網(wǎng)站互聯(lián)網(wǎng)營銷師證書
  • 購物網(wǎng)站怎么做代碼網(wǎng)站排名工具
  • 企業(yè)起名字大全最新版處理事件seo軟件
  • 廬江網(wǎng)站建設(shè)百度的總部在哪里
  • 彩票源碼論壇專業(yè)seo站長工具
  • 移動(dòng)版網(wǎng)站開發(fā)電商網(wǎng)站平臺(tái)搭建
  • 北京網(wǎng)站整站優(yōu)化網(wǎng)站流量指標(biāo)有哪些
  • 用什么做網(wǎng)站開發(fā)百度軟件應(yīng)用中心
  • 查詢網(wǎng)站開發(fā)外貿(mào)網(wǎng)站建設(shè)公司
  • 深圳汽車網(wǎng)站建設(shè)朝陽網(wǎng)站建設(shè)公司
  • 微信小程序在哪里登錄湘潭seo培訓(xùn)
  • 專門做招商的網(wǎng)站深圳推廣網(wǎng)絡(luò)
  • 闡述電子商務(wù)網(wǎng)站的建設(shè)要求深圳網(wǎng)絡(luò)推廣建站
  • 網(wǎng)站首頁 排版網(wǎng)絡(luò)營銷課程總結(jié)
  • 商業(yè)網(wǎng)站開發(fā)選題的目的哪些平臺(tái)可以做推廣
  • 王也諸葛青sem優(yōu)化軟件選哪家
  • 電子商務(wù)網(wǎng)站分析百度快照是干嘛的
  • 營銷型企業(yè)網(wǎng)站的功能網(wǎng)絡(luò)廣告營銷方案策劃內(nèi)容
  • 建設(shè)一個(gè)網(wǎng)站用什么搭建北京搜索排名優(yōu)化
  • 政府 網(wǎng)站建設(shè)方案推廣產(chǎn)品
  • 滑縣做網(wǎng)站公司制作網(wǎng)頁的基本步驟
  • 網(wǎng)站上的qq如何做懸浮百度seo公司
  • 企業(yè)網(wǎng)站排名怎么優(yōu)化西安網(wǎng)站建設(shè)公司電話
  • flash網(wǎng)站 seo常見的推廣方式
  • 我要建設(shè)一個(gè)網(wǎng)站微信小程序開發(fā)費(fèi)用一覽表
  • 中華人民共和國住房建設(shè)部網(wǎng)站seo自學(xué)網(wǎng)官網(wǎng)