成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ThreadLocal 內(nèi)部實現(xiàn)和應(yīng)用場景(慎用,可能有內(nèi)存泄露)

heartFollower / 1866人閱讀

摘要:而應(yīng)用場景更多是想共享一個變量,但是該變量又不是線程安全的,那么可以用維護一個線程一個實例。因為創(chuàng)建這個對象本身很費時的,而且我們也知道本身不是線程安全的,也不能緩存一個共享的實例,為此我們想到使用來給每個線程緩存一個實例,提高性能。

很多人都知道java中有ThreadLocal這個類,但是知道ThreadLocal這個類具體有什么作用,然后適用什么樣的業(yè)務(wù)場景還是很少的。今天我就嘗試以自己的理解,來講解下ThreadLocal類的內(nèi)部實現(xiàn)和應(yīng)用場景,如果有什么不對之處,還望大家指正。

首先明確一個概念,那就是ThreadLocal并不是用來并發(fā)控制訪問一個共同對象,而是為了給每個線程分配一個只屬于該線程的對象(這么粗暴的解釋可能還不太準(zhǔn)確),更準(zhǔn)確的說是為了實現(xiàn)線程間的數(shù)據(jù)隔離。而ThreadLocal應(yīng)用場景更多是想共享一個變量,但是該變量又不是線程安全的,那么可以用ThreadLocal維護一個線程一個實例。有時候ThreadLocal也可以用來避免一些參數(shù)傳遞,通過ThreadLocal來訪問對象。

首先我們先看下ThreadLocal(jdk1.7)內(nèi)部的實現(xiàn):
ThreadLocal get方法

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

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

get和set方法是ThreadLocal類中最常用的兩個方法。

  

get方法

代碼很容易理解,首先我們通過Thread.currentThread得到當(dāng)前線程,然后獲取當(dāng)前線程的threadLocals變量,這個變量就是ThreadLocalMap類型的。然后根據(jù)當(dāng)前的ThreadLocal實例作為key,獲取到Entry對象。

  

set方法

代碼同樣很容易理解。同樣根據(jù)Thread.currentThread得到當(dāng)前線程,如果當(dāng)前線程存在threadLocals這個變量不為空,那么根據(jù)當(dāng)前的ThreadLocal實例作為key尋找在map中位置,然后用新的value值來替換舊值。

在ThreadLocal這個類中比較引人注目的應(yīng)該是ThreadLocal->ThreadLocalMap->Entry這個類。這個類繼承自WeakReference。關(guān)于弱引用的知識,以后我會抽時間寫篇文章來介紹下。

最近在我們的web項目中servlet需要頻繁創(chuàng)建SimpleDateFormat這個對象,進行日期格式化。因為創(chuàng)建這個對象本身很費時的,而且我們也知道SimpleDateFormat本身不是線程安全的,也不能緩存一個共享的SimpleDateFormat實例,為此我們想到使用ThreadLocal來給每個線程緩存一個SimpleDateFormat實例,提高性能。同時因為每個Servlet會用到不同pattern的時間格式化類,所以我們對應(yīng)每一種pattern生成了一個ThreadLocal實例。

  

DateFormatFactory

public class DateFormatFactory {

private static final Map> pattern2ThreadLocal;

static {
    DatePattern[] patterns = DatePattern.values();
    int len = patterns.length;
    pattern2ThreadLocal = new HashMap>(len);

    for (int i = 0; i < len; i++) {
        DatePattern datePattern = patterns[i];
        final String pattern = datePattern.pattern;

        pattern2ThreadLocal.put(datePattern, new ThreadLocal() {
            @Override
            protected DateFormat initialValue() {
                return new SimpleDateFormat(pattern);
            }
        });
    }
}

//獲取DateFormat
public static DateFormat getDateFormat(DatePattern pattern) {
    ThreadLocal threadDateFormat = pattern2ThreadLocal.get(pattern);
    //不需要判斷threadDateFormat是否為空
    return threadDateFormat.get(); 
}

}

  

DatePattern 枚舉類

public enum DatePattern {

TimePattern("yyyy-MM-dd HH:mm:ss"),

DatePattern("yyyy-MM-dd"),

public String pattern;

private DatePattern(String pattern) {
    this.pattern = pattern;
}

}

這樣我們就可以每次調(diào)用DateFormatFactory.getDateFormat獲取到對應(yīng)的時間格式化類了。之前我們提到使用ThreadLocal同時可以避免參數(shù)傳遞。假如我們這個Servlet要調(diào)用到其他類的方法,而且方法內(nèi)需要使用時間格式化類。按照正常情況下我們把該時間格式化類作為參數(shù)進行傳遞,但如果有了ThreadLocal這個類,我們可以不需要作為參數(shù)傳遞了,可以在方法類通過ThreadLocal得到時間格式化類。當(dāng)然代碼的通用性就差了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64081.html

相關(guān)文章

  • ThreadLocal 線程安全機制與小地雷

    摘要:多線程類庫對于共享數(shù)據(jù)的讀寫控制主要采用鎖機制保證線程安全,本文所要探究的則采用了一種完全不同的策略。所以出現(xiàn)內(nèi)存泄露的前提必須是持有的線程一直存活,這在使用線程池時是很正常的,在這種情況下一直不會被,因為 Java 多線程類庫對于共享數(shù)據(jù)的讀寫控制主要采用鎖機制保證線程安全,本文所要探究的 ThreadLocal 則采用了一種完全不同的策略。ThreadLocal 不是用來解決共享數(shù)...

    xiao7cn 評論0 收藏0
  • (八)ThreadLocal的使用及原理分析

    摘要:什么是,簡單翻譯過來就是本地線程,但是直接這么翻譯很難理解的作用,如果換一種說法,可以稱為線程本地存儲。魔數(shù)的選取和斐波那契散列有關(guān),對應(yīng)的十進制為。而斐波那契散列的乘數(shù)可以用如果把這個值給轉(zhuǎn)為帶符號的,則會得到。 什么是ThreadLocal ThreadLocal,簡單翻譯過來就是本地線程,但是直接這么翻譯很難理解ThreadLocal的作用,如果換一種說法,可以稱為線程本地存儲。...

    asoren 評論0 收藏0
  • 深入了解Threadlocal

    摘要:通過將保存在中,每個線程都會擁有屬于自己的,代碼如下所示然后你就可以安心地調(diào)用了,不用考慮線程安全問題。這樣設(shè)計的好處就是,當(dāng)線程死掉之后,沒有強引用,方便收集器回收。 前言 想必大家都對Threadlocal很熟悉吧,今天我們就一起來深入學(xué)習(xí)一下。Threadlocal我更傾向于將其翻譯成線程局部變量。它有什么用處呢?Threadlocal對象通常用于防止對可變的單實例變量或全局變量...

    qiangdada 評論0 收藏0
  • 慎用ThreadLocal

    摘要:另載于是個很爽的東西,線程安全,能當(dāng)全局變量來用別。第一家公司,使用框架老技術(shù),現(xiàn)代人可以理解為類似,對每個請求都套上,進入時把寫入,返回或拋注意時清理。第二家公司,某次引入一個設(shè)計,也用了來傳遞上下文信息,有的地方?jīng)]能清掉。 另載于 http://www.qingjingjie.com/blogs/12 ThreadLocal是個很爽的東西,線程安全,能當(dāng)全局變量來用(別!)。 上一...

    harriszh 評論0 收藏0

發(fā)表評論

0條評論

heartFollower

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<