亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

java并發(fā)編程學(xué)習(xí)17--ThreadLocal

jayce / 1276人閱讀

摘要:概念類(lèi)用來(lái)存放線(xiàn)程的局部變量,每個(gè)線(xiàn)程都有自己的局部變量彼此之間不共享。返回當(dāng)前線(xiàn)程的局部變量初始值。工作流程的時(shí)候我們可以看見(jiàn)是從中獲取的,也就是說(shuō)這些局部變量真正存儲(chǔ)在中的時(shí)候從中獲取到了,然后再?gòu)闹蝎@取。和都用于解決多線(xiàn)程并發(fā)訪(fǎng)問(wèn)。

【概念

ThreadLocal類(lèi)用來(lái)存放線(xiàn)程的局部變量,每個(gè)線(xiàn)程都有自己的局部變量彼此之間不共享。TheadLocal主要有以下三個(gè)方法:

public T get():返回當(dāng)前線(xiàn)程的局部變量。

protected T initValue():返回當(dāng)前線(xiàn)程的局部變量初始值。默認(rèn)情況下 initValue(), 返回 null 。線(xiàn)程在沒(méi)有調(diào)用 set 之前,第一次調(diào)用 get 的時(shí)候, get 方法會(huì)默認(rèn)去調(diào)用 initValue 這個(gè)方法。所以如果沒(méi)有覆寫(xiě)這個(gè)方法,可能導(dǎo)致 get 返回的是 null 。當(dāng)然如果調(diào)用過(guò) set 就不會(huì)有這種情況了。

public void set(T value):設(shè)置當(dāng)前線(xiàn)程的局部變量。

ThreadLocal是如何做到為每一個(gè)線(xiàn)程提供多帶帶的局部變量呢?實(shí)際上在ThreadLocal類(lèi)中有一個(gè)Map緩存,用于存儲(chǔ)每一個(gè)線(xiàn)程的局部變量。Map中元素的鍵為線(xiàn)程對(duì)象,而值對(duì)應(yīng)線(xiàn)程的變量副本。

 /**
         * 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);
        }
【工作流程

1.set()的時(shí)候:

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

我們可以看見(jiàn)ThreadLocalMap是從currentThread中獲取的,也就是說(shuō)這些局部變量真正存儲(chǔ)在currentThread中:

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

2.get()的時(shí)候:

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

從currentThread中獲取到了ThreadLocalMap,然后再?gòu)闹蝎@取value。如果沒(méi)有值,則調(diào)用setInitialValue()。

【如何使用
package ThreadLocal;

import java.util.Random;

import static ThreadLocal.ThreadLocalTest.localSetter;

/**
 * 在每個(gè)線(xiàn)程中多帶帶存放一個(gè)值然后再獲取
 */
public class ThreadLocalTest {

    static ThreadLocal localSetter = new ThreadLocal();

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            MyThread t = new MyThread();
            t.start();
        }
    }
}
class MyThread extends Thread{

    private static Random random = new Random();

    @Override
    public void run(){
        //現(xiàn)在當(dāng)前線(xiàn)程中存入一個(gè)隨機(jī)變量 v1
        int randomVar = random.nextInt(100);
        localSetter.set(randomVar);
        System.out.println(getName() + " random is " + randomVar);
        //獲取當(dāng)前線(xiàn)程的隨機(jī)變量 v2
        //v1 永遠(yuǎn)等于 v2
        System.out.println(getName() + " localVar is " + localSetter.get());
    }
}
【spring與ThreadLocal

spring中的bean大多都是單例的,但是我們應(yīng)用又是支持并發(fā)的,所以將各個(gè)service,dao存放在ThreadLocal中是一個(gè)明智的做法。但是需要注意如果bean中包含共享變量,spring是沒(méi)有做任何的安全處理的。

【synchronized與ThreadLocal

ThreadLocal以空間換取時(shí)間,提供了一種非常簡(jiǎn)便的多線(xiàn)程實(shí)現(xiàn)方式。
ThreadLocal和Synchonized都用于解決多線(xiàn)程并發(fā)訪(fǎng)問(wèn)。但是ThreadLocal與synchronized有本質(zhì)的區(qū)別:
synchronized是利用鎖的機(jī)制,使變量或代碼塊在某一時(shí)該只能被一個(gè)線(xiàn)程訪(fǎng)問(wèn)。而ThreadLocal為每一個(gè)線(xiàn)程都提供了變量的副本。Synchronized用于線(xiàn)程間的數(shù)據(jù)共享,而ThreadLocal則用于線(xiàn)程間的數(shù)據(jù)隔離。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/68300.html

相關(guān)文章

  • Java多線(xiàn)程學(xué)習(xí)(七)并發(fā)編程中一些問(wèn)題

    摘要:相比與其他操作系統(tǒng)包括其他類(lèi)系統(tǒng)有很多的優(yōu)點(diǎn),其中有一項(xiàng)就是,其上下文切換和模式切換的時(shí)間消耗非常少。因?yàn)槎嗑€(xiàn)程競(jìng)爭(zhēng)鎖時(shí)會(huì)引起上下文切換。減少線(xiàn)程的使用。很多編程語(yǔ)言中都有協(xié)程。所以如何避免死鎖的產(chǎn)生,在我們使用并發(fā)編程時(shí)至關(guān)重要。 系列文章傳送門(mén): Java多線(xiàn)程學(xué)習(xí)(一)Java多線(xiàn)程入門(mén) Java多線(xiàn)程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線(xiàn)程學(xué)習(xí)(二)syn...

    dingding199389 評(píng)論0 收藏0
  • Java多線(xiàn)程學(xué)習(xí)(七)并發(fā)編程中一些問(wèn)題

    摘要:因?yàn)槎嗑€(xiàn)程競(jìng)爭(zhēng)鎖時(shí)會(huì)引起上下文切換。減少線(xiàn)程的使用。舉個(gè)例子如果說(shuō)服務(wù)器的帶寬只有,某個(gè)資源的下載速度是,系統(tǒng)啟動(dòng)個(gè)線(xiàn)程下載該資源并不會(huì)導(dǎo)致下載速度編程,所以在并發(fā)編程時(shí),需要考慮這些資源的限制。 最近私下做一項(xiàng)目,一bug幾日未解決,總惶恐。一日頓悟,bug不可怕,怕的是項(xiàng)目不存在bug,與其懼怕,何不與其剛正面。 系列文章傳送門(mén): Java多線(xiàn)程學(xué)習(xí)(一)Java多線(xiàn)程入門(mén) Jav...

    yimo 評(píng)論0 收藏0
  • 超實(shí)用百道Java面試題

    摘要:是的簡(jiǎn)稱(chēng),運(yùn)行環(huán)境,為的運(yùn)行提供了所需的環(huán)境。分割字符串,返回分割后的字符串?dāng)?shù)組。當(dāng)計(jì)算的值相同時(shí),我們稱(chēng)之為沖突,的做法是用鏈表和紅黑樹(shù)存儲(chǔ)相同的值的。迭代器取代了集合框架中的,迭代器允許調(diào)用者在迭代過(guò)程中移除元素。 Java基礎(chǔ)1.JDK和JRE有什么區(qū)別? JDK 是java development kit的簡(jiǎn)稱(chēng),java開(kāi)發(fā)工具包,提供java的開(kāi)發(fā)環(huán)境和運(yùn)行環(huán)境。JRE 是j...

    MkkHou 評(píng)論0 收藏0
  • java并發(fā)編程學(xué)習(xí)---之一

    摘要:開(kāi)始學(xué)習(xí)也有一段時(shí)間了,一些基礎(chǔ)的書(shū)也掃了一遍了。最近慢慢開(kāi)始看和,后者的話(huà)和有類(lèi)似之處,都是一些編程經(jīng)驗(yàn)的編程的世界里好多的東西都是相同的。這里其實(shí)是對(duì)的最佳實(shí)踐,之后該對(duì)象已經(jīng)變成一個(gè)過(guò)期的引用了,此時(shí)就應(yīng)該清空這個(gè)引用。 開(kāi)始學(xué)習(xí)java也有一段時(shí)間了,一些基礎(chǔ)的書(shū)也掃了一遍了(think in java/core java volume 1)。最近慢慢開(kāi)始看和,后者的話(huà)和有類(lèi)似...

    chavesgu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<