www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 技術(shù)學(xué)院 > 技術(shù)前線
[導(dǎo)讀]線程切換能夠在一個(gè) CPU 周期內(nèi)完成(實(shí)際上可以沒(méi)有開(kāi)銷(xiāo),上個(gè)周期在運(yùn)行線程A,下個(gè)周期就已在運(yùn)行線程B)。這樣子看起來(lái)像是每個(gè)線程是獨(dú)自運(yùn)行的,沒(méi)有其他線程與目前共享硬件資源。

線程(英語(yǔ):multithreading),是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計(jì)算機(jī)因有硬件支持而能夠在同一時(shí)間執(zhí)行多于一個(gè)線程,進(jìn)而提升整體處理性能。具有這種能力的系統(tǒng)包括對(duì)稱(chēng)多處理機(jī)、多核心處理器以及芯片級(jí)多處理或同時(shí)多線程處理器。

粗粒度交替多線程

一個(gè)線程持續(xù)運(yùn)行,直到該線程被一個(gè)事件擋住而制造出長(zhǎng)時(shí)間的延遲(可能是內(nèi)存load/store操作,或者程序分支操作)[4]。

舉例來(lái)說(shuō)

周期 i :接收線程 A 的指令 j周期 i+1:接收線程 A 的指令 j+1周期 i+2:接收線程 A 的指令 j+2,而這指令緩存失敗周期 i+3:線程調(diào)度器介入,切換到線程 B周期 i+4:接收線程 B 的指令 k周期 i+5:接收線程 B 的指令 k+1[5]硬件成本

此種多線程硬件支持的目標(biāo),是允許在擋住的線程與已就緒的線程中快速切換。

這些新增功能的硬件有這些優(yōu)勢(shì):

線程切換能夠在一個(gè) CPU 周期內(nèi)完成(實(shí)際上可以沒(méi)有開(kāi)銷(xiāo),上個(gè)周期在運(yùn)行線程A,下個(gè)周期就已在運(yùn)行線程B)。這樣子看起來(lái)像是每個(gè)線程是獨(dú)自運(yùn)行的,沒(méi)有其他線程與目前共享硬件資源。對(duì)操作系統(tǒng)來(lái)說(shuō),通常每個(gè)虛擬線程都被視做一個(gè)處理器。這樣就不需要很大的軟件變更(像是特別寫(xiě)支持多線程的操作系統(tǒng))。為了要在各個(gè)現(xiàn)行中的線程有效率的切換,每個(gè)現(xiàn)行中的線程需要有自己的暫存設(shè)置(register set)。像是為了能在兩個(gè)線程中快速切換,硬件的寄存器需要兩次例示(instantiated)。

細(xì)粒度交替式多線程

執(zhí)行過(guò)程很像桶形處理器(Barrel Processor)就像這樣:

周期 i :接收線程 A 的一個(gè)指令周期 i+1:接收線程 B 的一個(gè)指令周期 i+2:接收線程 C 的一個(gè)指令這種線程的效果是會(huì)將所有從運(yùn)行流水線中的資料從屬(data dependency)關(guān)系移除掉。因?yàn)槊總€(gè)線程是相對(duì)獨(dú)立,流水線中的一個(gè)指令層次結(jié)構(gòu)需要從已跑完流水線中的較舊指令代入輸出的機(jī)會(huì)就相對(duì)的變小了。而在概念上,這種多線程與操作系統(tǒng)的核心先占多任務(wù)(pre-exemptive multitasking)相似。

1.基本概念

進(jìn)程:在操作系統(tǒng)中運(yùn)行的程序就是進(jìn)程,比如:QQ、播放器等。

線程:一個(gè)進(jìn)程可以有多個(gè)線程,如:視頻可以同時(shí)聽(tīng)聲音、看圖像。

并行:多個(gè)cpu實(shí)例或者多臺(tái)機(jī)器同時(shí)執(zhí)行各自的處理邏輯,是真正的同時(shí)。

并發(fā):通過(guò)cpu調(diào)度算法,讓用戶看上去同時(shí)執(zhí)行,實(shí)際上從cpu操作層面不是真正的同時(shí)。

2.線程的生命周期

1)有新建(New)、就緒(Runnable)、運(yùn)行(Running)、阻塞(Blocked)、死亡(Dead)共5種狀態(tài)。

新建狀態(tài):new關(guān)鍵字新建一個(gè)線程后,該線程就處于新建狀態(tài),此時(shí)僅由JVM為其分配內(nèi)存,并初始化成員變量的值。

就緒狀態(tài):線程對(duì)象調(diào)用start()方法之后,該線程處于就緒狀態(tài)。Java虛擬機(jī)會(huì)為其創(chuàng)建方法調(diào)用棧和程序計(jì)數(shù)器,等待調(diào)度運(yùn)行。

運(yùn)行狀態(tài):處于就緒狀態(tài)的線程獲得了CPU,開(kāi)始執(zhí)行run()方法的線程執(zhí)行體,此時(shí)該線程處于運(yùn)行狀態(tài)。

阻塞狀態(tài):處于運(yùn)行狀態(tài)的線程失去所占用資源后,便進(jìn)入阻塞狀態(tài)。

死亡狀態(tài):線程run()方法執(zhí)行結(jié)束后進(jìn)入死亡狀態(tài)。此外,如果線程執(zhí)行了interrupt()或stop()方法,也會(huì)以異常退出的方式進(jìn)入死亡狀態(tài)。

2)線程狀態(tài)的控制:

start():?jiǎn)?dòng)當(dāng)前線程,自動(dòng)調(diào)用當(dāng)前線程的run()方法。

run():通常需要重寫(xiě)Thread類(lèi)中的此方法,將創(chuàng)建的線程要執(zhí)行的操作方法聲明在此方法中。

yield():釋放當(dāng)前CPU的執(zhí)行權(quán)。

join():若線程a中調(diào)用線程b的join(),則線程a進(jìn)入阻塞狀態(tài),直到線程b執(zhí)行完成后線程a才結(jié)束阻塞狀態(tài)。

sleep(long militime):讓線程睡眠指定的毫秒數(shù),指定時(shí)間內(nèi),線程是阻塞狀態(tài),不會(huì)釋放鎖。該方法可以再任何場(chǎng)景下調(diào)用。

wait():執(zhí)行此方法,當(dāng)前線程會(huì)進(jìn)入阻塞狀態(tài),并釋放同步監(jiān)視器(鎖)。該方法必須在同步代碼塊和同步方法中才能調(diào)用。

notify():?jiǎn)拘驯粀ait的一個(gè)線程,多個(gè)線程wait時(shí),喚醒優(yōu)先度最高的。

notifyAll():?jiǎn)拘阉斜粀ait的線程。

LockSupport():LockSupport.park()和LockSupport.unpark()實(shí)現(xiàn)線程的阻塞和喚醒。

3.多線程的5種創(chuàng)建方式

① 繼承Thread類(lèi),重寫(xiě)run()方法。

② 實(shí)現(xiàn)Runnable接口,重寫(xiě)run()方法。

③ 匿名內(nèi)部類(lèi)的方式,重寫(xiě)run()方法。相當(dāng)于繼承了Thread類(lèi)。new Thread(){ public void run(){邏輯功能} }.start();

④ Lambda表達(dá)式創(chuàng)建,相當(dāng)于實(shí)現(xiàn)Runnable接口的方法。new Thread(()->{邏輯功能}).start();

⑤ 線程池創(chuàng)建。Executor pool = Executors.newFixedThreadPool(); pool.excute(new Runnable(){public void run(){邏輯功能}});

線程池創(chuàng)建的一些參數(shù):

corePoolSize:隊(duì)列沒(méi)滿時(shí),線程最大并發(fā)數(shù)。

maximumPoolSizes:隊(duì)列滿后線程能夠達(dá)到的最大并發(fā)數(shù)。

keepAliveTime:空閑線程過(guò)多久被回收的時(shí)間限制。

unit:keepAliveTime的時(shí)間單位。

workQueue:阻塞的隊(duì)列類(lèi)型。

RejectedExecutionHandler:超出maximumPoolSizes + workQueue時(shí),任務(wù)會(huì)交給RejectedExecutionHandler來(lái)處理。

4.線程的同步

為了防止多個(gè)線程訪問(wèn)一個(gè)數(shù)據(jù)對(duì)象時(shí),對(duì)數(shù)據(jù)造成破壞,采用線程同步來(lái)保證多線程安全訪問(wèn)競(jìng)爭(zhēng)資源。

1)普通同步方法:synchronized關(guān)鍵字加在普通方法上,此時(shí)鎖就是當(dāng)前實(shí)例對(duì)象,進(jìn)入同步方法前要獲取當(dāng)前實(shí)例的鎖。

2)靜態(tài)同步方法:synchronized關(guān)鍵字加在靜態(tài)方法上,此時(shí)鎖就是當(dāng)前類(lèi)的class對(duì)象,進(jìn)入同步方法前要獲取當(dāng)前類(lèi)對(duì)象的鎖。

3)同步方法塊:synchronized關(guān)鍵字加在代碼塊前,小括號(hào)中指定鎖是什么,進(jìn)入同步代碼塊前就需要獲取指定的鎖。

synchronized底層實(shí)現(xiàn):

數(shù)據(jù)在JVM內(nèi)存的存儲(chǔ):Java對(duì)象頭、moniter對(duì)象監(jiān)視器。

① 在JVM虛擬機(jī)中,對(duì)象在內(nèi)存中的存儲(chǔ)布局分為三個(gè)區(qū)域:對(duì)象頭(Header)、實(shí)例數(shù)據(jù)(Instance Data)、對(duì)齊填充(Padding)。Java對(duì)象頭包括:類(lèi)型指針(Klass Pointer)和標(biāo)記字段(Mark Word)。類(lèi)型指針是對(duì)象只想它的類(lèi)元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定該對(duì)象是哪個(gè)類(lèi)的實(shí)例。標(biāo)記字段用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),比如哈希碼、鎖狀態(tài)標(biāo)志、線程持有的鎖等。所以,synchronized使用的鎖對(duì)象是存儲(chǔ)在Java對(duì)象頭里的標(biāo)記字段里。

② moniter:對(duì)象監(jiān)視器可以類(lèi)比為一個(gè)特殊的房間,房間中有一些被保護(hù)的數(shù)據(jù),monitor保證每次只有一個(gè)線程能進(jìn)入房間,進(jìn)入即為持有monitor,退出即為釋放monitor。使用synchronized加鎖的同步代碼塊在字節(jié)碼引擎中執(zhí)行時(shí),主要就是通過(guò)鎖對(duì)象monitor的取用(monitorenter)與釋放(monitorexit)來(lái)實(shí)現(xiàn)的。

5.多線程引入問(wèn)題

1)線程安全問(wèn)題

① 原子性:常通過(guò)synchronized或者ReentrantLock來(lái)保證原子性。

② 可見(jiàn)性:指一個(gè)線程修改了某個(gè)變量值,其他線程能夠立即得到這個(gè)修改的值。每個(gè)線程都有自己的工作內(nèi)存,工作內(nèi)存和主存間要通過(guò)store和load進(jìn)行交互??梢?jiàn)性問(wèn)題常使用volatile關(guān)鍵字解決。當(dāng)一個(gè)共享變量被volatile修飾時(shí),它會(huì)保證修改的值立即更新到主存,當(dāng)其他線程需要讀取時(shí),會(huì)去主存中讀取新值,而普通共享變量不能保證可見(jiàn)性,因?yàn)槠浔恍薷暮笏⑿禄刂鞔娴臅r(shí)間是不確定的。

2)線程死鎖

由于兩個(gè)或多個(gè)線程互相持有對(duì)方所需的資源,導(dǎo)致線程都處于等待狀態(tài),無(wú)法繼續(xù)執(zhí)行。

3)上下文切換

多線程有線程創(chuàng)建和線程上下文切換的開(kāi)銷(xiāo)。CPU通常會(huì)給不同的線程分配時(shí)間片,當(dāng)CPU從一個(gè)線程切換到另外一個(gè)線程的時(shí)候,CPU需要保存當(dāng)前線程的本地?cái)?shù)據(jù),程序指針等狀態(tài),并加載下一個(gè)要執(zhí)行的線程的本地?cái)?shù)據(jù)、程序指針等,這個(gè)切換就稱(chēng)為上下文切換。通常使用無(wú)鎖并發(fā)編程、CAS算法、協(xié)程等方式解決。

6.使用ReentrantLock

Java語(yǔ)言直接提供了synchronized關(guān)鍵字用于加鎖,但這種鎖存在兩個(gè)問(wèn)題:①很重,②獲取時(shí)必須一直等待,沒(méi)有額外的嘗試機(jī)制。java.util.concurrent.locks包提供的ReentrantLock用于替代synchronized加鎖。調(diào)用ReentrantLock()對(duì)象的lock()方法獲取鎖,最后調(diào)用unlock()方法手動(dòng)釋放鎖。ReentrantLock是可重入鎖,和synchronized一樣,一個(gè)線程可以多次獲取同一個(gè)鎖。和synchronized不同的是,ReentrantLock可以嘗試獲取鎖,即:調(diào)用ReentrantLock()對(duì)象的tryLock()方法,其中傳入等待時(shí)間,時(shí)間單位,如果在這個(gè)時(shí)間后仍然沒(méi)有獲取到鎖,tryLock()方法會(huì)返回false,程序可以去做其他事情。

synchronized可以配合wait()和notify()實(shí)現(xiàn)線程在條件不滿足時(shí)等待,條件滿足時(shí)喚醒,而ReentrantLock則需要借助Condition對(duì)象來(lái)實(shí)現(xiàn),注意Condition對(duì)象必須來(lái)自于ReentrantLock()對(duì)象調(diào)用newCondition()方法,這樣才能獲得一個(gè)綁定了ReentrantLock實(shí)例的Condition實(shí)例。Condition提供了await()、signal()、signalAll()方法,與wait()、notify()、notifyAll()是一致的。

① await():會(huì)釋放當(dāng)前鎖,進(jìn)入等待狀態(tài);

② signal():會(huì)喚醒某個(gè)等待線程;

③ signalAll():會(huì)喚醒所有等待線程;

此外,和tryLock()類(lèi)似,await()可以在等待指定時(shí)間后,如果還沒(méi)有被其他線程通過(guò)signal()或signalAll()喚醒,可以自己醒來(lái):

if ( condition.await(1, TimeUnit.SECOND) ) {

// 被其他線程喚醒

} else {

// 指定時(shí)間內(nèi)沒(méi)有被其他線程喚醒

}

7.使用ReadWriteLock

ReentrantLock保證了只有一個(gè)線程可以執(zhí)行臨界區(qū)代碼,但是有些時(shí)候,這種保護(hù)有點(diǎn)過(guò)頭。有些方法只是讀取數(shù)據(jù),并不修改數(shù)據(jù),此時(shí)應(yīng)該允許多個(gè)線程同時(shí)調(diào)用才對(duì)。使用ReadWriteLock可以解決這個(gè)問(wèn)題,它可以保證:

① 只允許一個(gè)線程寫(xiě)入(此時(shí)其他線程既不能寫(xiě)入也不能讀取);

② 沒(méi)有寫(xiě)入時(shí),多個(gè)線程允許同時(shí)讀(提高性能);

使用方法:new出來(lái)ReadWriteLock()對(duì)象實(shí)例后,調(diào)用該對(duì)象的readLock()和writeLock()分別獲取讀鎖和寫(xiě)鎖實(shí)例,接著在讀方法中使用讀鎖,寫(xiě)方法中使用寫(xiě)鎖。

private final ReadWriteLock rwlock = new ReentrantReadWriteLock();

private final Lock rlock = rwlock.readLock();

private final Lock wlock = rwlock.writeLock();

8.使用StampedLock

ReadWriteLock讀的過(guò)程中不允許寫(xiě),是一種悲觀的讀鎖。其實(shí)讀的過(guò)程中大概率不會(huì)有寫(xiě)操作的發(fā)生,所以并發(fā)效率有待提高。StampedLock和ReadWriteLock相比,讀的過(guò)程中也允許獲取寫(xiě)鎖后寫(xiě)入。這樣一來(lái),我們讀的數(shù)據(jù)就可能不一致,所以,需要一點(diǎn)額外的代碼來(lái)判斷讀的過(guò)程中是否有寫(xiě)入,這種讀鎖是一種樂(lè)觀鎖。StampedLock是不可重入鎖,不能在一個(gè)線程中反復(fù)獲取同一個(gè)鎖。其提供了將悲觀讀鎖升級(jí)為寫(xiě)鎖的功能,它主要使用在if-then-update的場(chǎng)景:即先讀,如果讀的數(shù)據(jù)滿足條件,就返回,如果讀的數(shù)據(jù)不滿足條件,再嘗試寫(xiě)。

使用方法:new出來(lái)StampedLock()對(duì)象實(shí)例后,調(diào)用該對(duì)象的readLock()和writeLock()可以分別獲取讀鎖和寫(xiě)鎖實(shí)例并上鎖,同時(shí)還會(huì)返回版本號(hào),釋放的時(shí)候調(diào)用unclockWrite()或者unlockRead()方法需要傳入版本號(hào)。調(diào)用tryOptimisticRead()獲得樂(lè)觀讀鎖,同時(shí)返回版本號(hào),它在操作數(shù)據(jù)前并沒(méi)有通過(guò) CAS設(shè)置鎖的狀態(tài),僅僅通過(guò)位運(yùn)算測(cè)試,所以不需要顯式地釋放鎖。通常獲取樂(lè)觀鎖,讀入數(shù)據(jù)后,會(huì)調(diào)用validate()方法傳入版本號(hào)stamp進(jìn)行驗(yàn)證,如果中途有寫(xiě)入,則版本號(hào)會(huì)發(fā)生變化,方法會(huì)返回false,此時(shí)需要通過(guò)獲得悲觀鎖再重新讀入數(shù)據(jù)。

9.使用Semaphore

上面的鎖保證同一時(shí)刻只有一個(gè)線程能訪問(wèn)(ReentrantLock),或者只有一個(gè)線程能寫(xiě)入(ReadWriteLock)。還有一種受限資源,需要保證同一時(shí)刻最多有N個(gè)線程能訪問(wèn),比如同一時(shí)刻最多創(chuàng)建100個(gè)數(shù)據(jù)庫(kù)連接,最多允許10個(gè)用戶下載等。這種限制數(shù)量的鎖,用Lock數(shù)組來(lái)實(shí)現(xiàn)很麻煩,此時(shí)就可以使用可以使用Semaphore。其本質(zhì)上就是一個(gè)信號(hào)計(jì)數(shù)器,用于限制同一時(shí)間的最大訪問(wèn)數(shù)量。

使用方法:new出來(lái)Semaphore()對(duì)象實(shí)例,其中傳入允許訪問(wèn)的線程數(shù)量,在需要控制的方法中,調(diào)用acquire()方法,接著完成功能邏輯,最后調(diào)用release()方法釋放。調(diào)用acquire()可能會(huì)進(jìn)入等待,直到滿足條件為止。也可以使用tryAcquire()指定等待時(shí)間。

10.使用Future

Runnable接口有個(gè)問(wèn)題,它的方法沒(méi)有返回值。如果任務(wù)需要一個(gè)返回結(jié)果,那么只能保存到變量,還要提供額外的方法讀取,非常不方便。Callable接口和Runnable接口比,多了一個(gè)返回值功能,并且Callable接口是一個(gè)泛型接口,可以返回指定結(jié)果的類(lèi)型。線程池對(duì)象的submit()方法提交任務(wù)執(zhí)行后會(huì)返回一個(gè)Future對(duì)象,也支持泛型,其表示一個(gè)未來(lái)能獲得結(jié)果的對(duì)象。當(dāng)我們提交一個(gè)Callable任務(wù)后,我們會(huì)同時(shí)獲得一個(gè)Future對(duì)象,然后,我們?cè)谥骶€程某個(gè)時(shí)刻調(diào)用Future對(duì)象的get()方法,就可以獲得異步執(zhí)行的結(jié)果。在調(diào)用get()時(shí),如果異步任務(wù)已經(jīng)完成,我們就直接獲得結(jié)果。如果異步任務(wù)還沒(méi)有完成,那么get()會(huì)阻塞,直到任務(wù)完成后才返回結(jié)果。

Future接口定義的方法有:

get():獲取結(jié)果(可能會(huì)等待);

get(long timeout, TimeUnit unit):獲取結(jié)果,但只等待指定的時(shí)間;

cancel(boolean mayInterruptIfRunning):取消當(dāng)前任務(wù);

isDone():判斷任務(wù)是否已完成。

11.使用CompletableFuture

使用Future獲得異步執(zhí)行結(jié)果時(shí),要么調(diào)用阻塞方法get(),要么輪詢看isDone()是否為true,這兩種方法都不是很好,因?yàn)橹骶€程也會(huì)被迫等待。CompletableFuture針對(duì)Future做了改進(jìn),可以傳入回調(diào)對(duì)象,當(dāng)異步任務(wù)完成或者發(fā)生異常時(shí),自動(dòng)調(diào)用回調(diào)對(duì)象的回調(diào)方法。

使用方式:調(diào)用CompletableFuture的supplyAsync()創(chuàng)建CompletableFuture對(duì)象,其中傳入實(shí)現(xiàn)了Supplier接口的對(duì)象(無(wú)傳入值,有返回值),他會(huì)被提交給默認(rèn)的線程執(zhí)行。調(diào)用thenAccept()方法,其接收實(shí)現(xiàn)了Consumer接口的對(duì)象(有傳入值,無(wú)返回值),設(shè)置執(zhí)行完成時(shí)的回調(diào)方法。調(diào)用exceptionally()方法,接收實(shí)現(xiàn)了Function接口的對(duì)象,設(shè)置報(bào)異常時(shí)的回調(diào)方法。

12.使用ForkJoin

Java 7開(kāi)始引入了一種新的Fork/Join線程池,它可以執(zhí)行一種特殊的任務(wù):把一個(gè)大任務(wù)拆成多個(gè)小任務(wù)并行執(zhí)行。

比如:計(jì)算一個(gè)超大數(shù)組的和,可以把數(shù)組拆成兩部分,分別計(jì)算,最后加起來(lái)就是最終結(jié)果,這樣可以用兩個(gè)線程并行執(zhí)行,如果拆成兩部分還是很大,我們還可以繼續(xù)拆,用4個(gè)線程并行執(zhí)行。這就是Fork/Join任務(wù)的原理:判斷一個(gè)任務(wù)是否足夠小,如果是,直接計(jì)算,否則,就分拆成幾個(gè)小任務(wù)分別計(jì)算。這個(gè)過(guò)程可以反復(fù)“裂變”成一系列小任務(wù)。

使用方法:新建類(lèi)繼承RecursiveTask,其中重寫(xiě)compute方法,設(shè)定閾值,如果任務(wù)小于設(shè)定的閾值,就直接計(jì)算,最后返回結(jié)果。如果任務(wù)大于設(shè)定的閾值,就分裂成兩個(gè)小任務(wù),調(diào)用invokeAll()傳入兩個(gè)小任務(wù),再分別調(diào)用兩個(gè)小任務(wù)的join()方法來(lái)得到返回結(jié)果,最后將兩個(gè)結(jié)果加起來(lái)返回。

13. 使用ThreadLocal

上下文(Context):在一個(gè)線程中,橫跨若干方法調(diào)用,需要傳遞的對(duì)象,通常稱(chēng)之為上下文(Context),它是一種狀態(tài),可以是用戶身份、任務(wù)信息等。

Web應(yīng)用程序是典型的多任務(wù)應(yīng)用,每個(gè)用戶請(qǐng)求頁(yè)面時(shí),我們都會(huì)創(chuàng)建一個(gè)任務(wù),去完成類(lèi)似以下的工作:檢查權(quán)限、做工作、保存狀態(tài)、發(fā)送響應(yīng)。如果這些工作中也需要用到上下文(context),此處就是user實(shí)例,可以簡(jiǎn)單地直接通過(guò)參數(shù)傳入,但是往往一個(gè)方法又會(huì)調(diào)用其他很多方法,這樣會(huì)導(dǎo)致User傳遞到所有地方,但是給每個(gè)方法都增加一個(gè)Context參數(shù)非常麻煩,而且如果調(diào)用鏈中有無(wú)法修改源碼的第三方庫(kù),context就傳不進(jìn)去了。ThreadLocal就很適合解決這個(gè)問(wèn)題,它可以在一個(gè)線程中傳遞同一個(gè)對(duì)象。

public void process(User user) {

checkPermission();

doWork();

saveStatus();

sendResponse();

}

使用方法:ThreadLocal實(shí)例通??偸且造o態(tài)字段初始化,通過(guò)設(shè)置一個(gè)User實(shí)例關(guān)聯(lián)到ThreadLocal中,在移除之前,所有方法都可以隨時(shí)獲取到該User實(shí)例。普通的方法調(diào)用一定是同一個(gè)線程執(zhí)行的,所以,該線程中所有方法調(diào)用threadLocalUser.get()獲取的User對(duì)象是同一個(gè)實(shí)例。ThreadLocal相當(dāng)于給每個(gè)線程都開(kāi)辟了一個(gè)獨(dú)立的存儲(chǔ)空間,各個(gè)線程的ThreadLocal關(guān)聯(lián)的實(shí)例互不干擾,特別注意ThreadLocal一定要在finally中清除。因?yàn)楫?dāng)前線程執(zhí)行完相關(guān)代碼后,很可能會(huì)被重新放入線程池中,如果ThreadLocal沒(méi)有被清除,該線程執(zhí)行其他代碼時(shí),會(huì)把上一次的狀態(tài)帶進(jìn)去。其實(shí),可以ThreadLocal看成一個(gè)全局Map:每個(gè)線程獲取ThreadLocal變量時(shí),總是使用Thread自身作為key。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉