版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2025年高頻java多線程編程面試題及答案Q:線程的六種狀態(tài)及其轉(zhuǎn)換條件是什么?A:Java線程在生命周期中共有六種狀態(tài),定義于Thread.State枚舉類(lèi)中:1.NEW(新建):線程對(duì)象已創(chuàng)建但未調(diào)用start()方法,此時(shí)線程尚未啟動(dòng)。2.RUNNABLE(可運(yùn)行):線程調(diào)用start()后進(jìn)入此狀態(tài),實(shí)際可能正在運(yùn)行(獲得CPU時(shí)間片)或等待CPU調(diào)度(在就緒隊(duì)列中)。Java將操作系統(tǒng)中的“運(yùn)行”和“就緒”狀態(tài)統(tǒng)一為RUNNABLE。3.BLOCKED(阻塞):線程試圖獲取synchronized同步鎖但未成功時(shí)進(jìn)入此狀態(tài),等待鎖釋放后重新競(jìng)爭(zhēng)鎖,回到RUNNABLE。4.WAITING(無(wú)限等待):線程調(diào)用無(wú)參的wait()(需在synchronized塊中)、join()(等待目標(biāo)線程結(jié)束)或LockSupport.park()后進(jìn)入此狀態(tài),需其他線程調(diào)用notify()/notifyAll()、目標(biāo)線程結(jié)束或LockSupport.unpark()喚醒,回到RUNNABLE。5.TIMED_WAITING(計(jì)時(shí)等待):調(diào)用有超時(shí)參數(shù)的wait(long)、sleep(long)、join(long)或parkNanos(long)/parkUntil(long)后進(jìn)入此狀態(tài),超時(shí)后自動(dòng)喚醒,或提前被喚醒,回到RUNNABLE。6.TERMINATED(終止):線程執(zhí)行完run()方法或因異常終止后進(jìn)入此狀態(tài),生命周期結(jié)束。狀態(tài)轉(zhuǎn)換的關(guān)鍵觸發(fā)點(diǎn)包括:start()觸發(fā)NEW→RUNNABLE;獲取不到鎖觸發(fā)RUNNABLE→BLOCKED;主動(dòng)等待觸發(fā)RUNNABLE→WAITING/TIMED_WAITING;喚醒或超時(shí)觸發(fā)WAITING/TIMED_WAITING→RUNNABLE;線程執(zhí)行完畢觸發(fā)RUNNABLE→TERMINATED。Q:synchronized關(guān)鍵字的底層實(shí)現(xiàn)原理是什么?JDK1.6之后做了哪些優(yōu)化?A:synchronized的底層依賴JVM的管程(Monitor)機(jī)制實(shí)現(xiàn)同步。每個(gè)Java對(duì)象(包括類(lèi)對(duì)象)都關(guān)聯(lián)一個(gè)Monitor對(duì)象,其內(nèi)部包含計(jì)數(shù)器(記錄鎖的重入次數(shù))、所有者(當(dāng)前持有鎖的線程)和等待隊(duì)列(存儲(chǔ)被阻塞的線程)。當(dāng)線程進(jìn)入synchronized修飾的代碼塊或方法時(shí),會(huì)嘗試獲取對(duì)象關(guān)聯(lián)的Monitor:若計(jì)數(shù)器為0,線程獲取鎖并將計(jì)數(shù)器置1(重入時(shí)計(jì)數(shù)器遞增);若被其他線程持有,則進(jìn)入等待隊(duì)列,狀態(tài)轉(zhuǎn)為BLOCKED。JDK1.6為優(yōu)化synchronized的性能,引入了鎖升級(jí)(鎖膨脹)機(jī)制,根據(jù)競(jìng)爭(zhēng)程度動(dòng)態(tài)調(diào)整鎖狀態(tài),降低線程阻塞的開(kāi)銷(xiāo):1.偏向鎖:假設(shè)鎖僅被同一線程多次獲取,在對(duì)象頭MarkWord中記錄偏向線程ID,避免每次加鎖/解鎖的CAS操作。當(dāng)其他線程嘗試競(jìng)爭(zhēng)時(shí),偏向鎖升級(jí)為輕量級(jí)鎖。2.輕量級(jí)鎖:通過(guò)CAS操作嘗試將對(duì)象頭的MarkWord替換為指向線程棧中鎖記錄的指針。若CAS成功,線程獲得鎖;若失?。ù嬖诟?jìng)爭(zhēng)),升級(jí)為重量級(jí)鎖(傳統(tǒng)Monitor鎖)。3.自旋鎖:線程競(jìng)爭(zhēng)輕量級(jí)鎖失敗時(shí),不立即阻塞,而是自旋(空循環(huán))若干次嘗試重新獲取鎖,減少線程切換的開(kāi)銷(xiāo)(適用于鎖持有時(shí)間短的場(chǎng)景)。4.鎖消除:JIT編譯器通過(guò)逃逸分析,若發(fā)現(xiàn)鎖保護(hù)的代碼不會(huì)被其他線程訪問(wèn)(如局部變量對(duì)象),則消除不必要的鎖。5.鎖粗化:將連續(xù)的多次加鎖/解鎖操作合并為一次,減少鎖操作的開(kāi)銷(xiāo)(如循環(huán)內(nèi)對(duì)同一對(duì)象多次加鎖)。Q:synchronized和ReentrantLock的核心區(qū)別有哪些?A:synchronized和ReentrantLock均用于實(shí)現(xiàn)線程同步,但在功能和底層實(shí)現(xiàn)上有顯著差異:1.鎖的獲取方式:synchronized是Java關(guān)鍵字,依賴JVM實(shí)現(xiàn);ReentrantLock是java.util.concurrent.locks包下的類(lèi),基于AQS(AbstractQueuedSynchronizer)手動(dòng)實(shí)現(xiàn)。2.可中斷性:synchronized獲取鎖時(shí)不可中斷,線程若被阻塞會(huì)一直等待;ReentrantLock提供lockInterruptibly()方法,允許線程在等待鎖時(shí)響應(yīng)中斷(拋出InterruptedException)。3.公平性:synchronized默認(rèn)是非公平鎖(新線程可能搶占已等待的線程);ReentrantLock通過(guò)構(gòu)造函數(shù)參數(shù)(fair=true)支持公平鎖(按等待隊(duì)列順序分配鎖),但公平鎖會(huì)降低吞吐量。4.條件變量:synchronized通過(guò)Object的wait()/notify()/notifyAll()實(shí)現(xiàn)線程通信,僅支持一個(gè)等待隊(duì)列;ReentrantLock通過(guò)newCondition()獲取多個(gè)Condition對(duì)象,每個(gè)Condition對(duì)應(yīng)獨(dú)立的等待隊(duì)列,支持精準(zhǔn)喚醒(如喚醒特定條件的線程)。5.鎖的粒度控制:synchronized的鎖范圍由代碼塊或方法邊界決定,無(wú)法手動(dòng)釋放;ReentrantLock需顯式調(diào)用lock()獲取鎖、unlock()釋放鎖(通常在finally塊中執(zhí)行),靈活性更高。6.性能差異:早期版本synchronized性能較差,但JDK1.6優(yōu)化后(如鎖升級(jí))與ReentrantLock性能接近;高競(jìng)爭(zhēng)場(chǎng)景下,ReentrantLock的可調(diào)節(jié)參數(shù)(如自旋次數(shù))可能更優(yōu)。Q:線程池的核心參數(shù)有哪些?各參數(shù)的作用是什么?A:線程池通過(guò)ThreadPoolExecutor類(lèi)實(shí)現(xiàn),其構(gòu)造函數(shù)包含7個(gè)核心參數(shù):1.corePoolSize(核心線程數(shù)):線程池長(zhǎng)期保留的最小線程數(shù)(即使空閑也不會(huì)被銷(xiāo)毀,除非設(shè)置allowCoreThreadTimeOut為true)。2.maximumPoolSize(最大線程數(shù)):線程池允許創(chuàng)建的最大線程數(shù),當(dāng)任務(wù)隊(duì)列滿且當(dāng)前線程數(shù)小于此值時(shí),會(huì)創(chuàng)建新線程處理任務(wù)。3.keepAliveTime(存活時(shí)間):非核心線程(超過(guò)corePoolSize的線程)在空閑時(shí)的存活時(shí)間,超時(shí)后會(huì)被銷(xiāo)毀。若allowCoreThreadTimeOut為true,核心線程也適用此規(guī)則。4.unit(時(shí)間單位):keepAliveTime的時(shí)間單位(如TimeUnit.SECONDS)。5.workQueue(任務(wù)隊(duì)列):用于存儲(chǔ)待執(zhí)行任務(wù)的阻塞隊(duì)列,常見(jiàn)類(lèi)型包括:ArrayBlockingQueue(有界隊(duì)列,需指定容量);LinkedBlockingQueue(無(wú)界隊(duì)列,默認(rèn)容量為Integer.MAX_VALUE,可能導(dǎo)致OOM);SynchronousQueue(同步隊(duì)列,不存儲(chǔ)任務(wù),直接將任務(wù)提交給線程);PriorityBlockingQueue(優(yōu)先隊(duì)列,按任務(wù)優(yōu)先級(jí)排序)。6.threadFactory(線程工廠):用于創(chuàng)建工作線程,可自定義線程命名、優(yōu)先級(jí)等屬性(如Executors.defaultThreadFactory())。7.handler(拒絕策略):當(dāng)任務(wù)隊(duì)列滿且線程數(shù)達(dá)到maximumPoolSize時(shí),對(duì)新提交任務(wù)的處理策略,JDK提供4種實(shí)現(xiàn):AbortPolicy(默認(rèn)):拋出RejectedExecutionException異常;CallerRunsPolicy:由調(diào)用者線程(提交任務(wù)的線程)直接執(zhí)行任務(wù);DiscardPolicy:靜默丟棄新任務(wù);DiscardOldestPolicy:丟棄隊(duì)列中最舊的任務(wù),然后嘗試重新提交當(dāng)前任務(wù)。Q:如何合理配置線程池的核心線程數(shù)和最大線程數(shù)?A:線程池參數(shù)的配置需結(jié)合任務(wù)類(lèi)型(CPU密集型、IO密集型)和系統(tǒng)資源(CPU核心數(shù)、內(nèi)存)綜合考慮:1.CPU密集型任務(wù):任務(wù)主要消耗CPU資源(如計(jì)算、加密),線程空閑時(shí)間少。核心線程數(shù)建議設(shè)置為CPU核心數(shù)+1(+1用于處理偶發(fā)的頁(yè)缺失或其他中斷),最大線程數(shù)與核心線程數(shù)相同(避免過(guò)多線程競(jìng)爭(zhēng)CPU)。公式參考:corePoolSize=Runtime.getRuntime().availableProcessors()+1。2.IO密集型任務(wù):任務(wù)因IO操作(如數(shù)據(jù)庫(kù)查詢、網(wǎng)絡(luò)請(qǐng)求)導(dǎo)致線程大量空閑,CPU利用率低。此時(shí)可適當(dāng)增加線程數(shù),使CPU在等待IO時(shí)處理其他任務(wù)。核心線程數(shù)建議設(shè)置為2CPU核心數(shù)(或根據(jù)實(shí)際測(cè)試調(diào)整),最大線程數(shù)可設(shè)為核心線程數(shù)的1.5-2倍(需結(jié)合任務(wù)隊(duì)列容量和系統(tǒng)內(nèi)存限制)。3.混合任務(wù):同時(shí)包含CPU和IO操作的任務(wù),需通過(guò)壓測(cè)確定最優(yōu)配置??上冉y(tǒng)計(jì)任務(wù)中CPU耗時(shí)與IO耗時(shí)的比例(如CPU耗時(shí)占20%,IO占80%),再根據(jù)阿姆達(dá)爾定律估算合理線程數(shù)。4.注意事項(xiàng):避免設(shè)置過(guò)大的maximumPoolSize(可能導(dǎo)致線程切換開(kāi)銷(xiāo)劇增),優(yōu)先使用有界隊(duì)列(防止無(wú)界隊(duì)列導(dǎo)致OOM),拒絕策略需根據(jù)業(yè)務(wù)需求選擇(如金融交易場(chǎng)景用AbortPolicy快速暴露問(wèn)題,日志收集場(chǎng)景用DiscardPolicy減少影響)。Q:volatile關(guān)鍵字的作用是什么?與synchronized的區(qū)別有哪些?A:volatile是Java提供的輕量級(jí)同步機(jī)制,主要有兩大作用:1.保證可見(jiàn)性:被volatile修飾的變量,其修改對(duì)所有線程立即可見(jiàn)。JVM通過(guò)在寫(xiě)操作后插入“內(nèi)存屏障”(StoreBarrier),強(qiáng)制將變量值刷新到主內(nèi)存;讀操作前插入“內(nèi)存屏障”(LoadBarrier),強(qiáng)制從主內(nèi)存讀取最新值,避免線程使用本地緩存的舊值。2.禁止指令重排:通過(guò)內(nèi)存屏障限制編譯器和CPU對(duì)指令的重排序優(yōu)化,確保代碼的邏輯順序與執(zhí)行順序一致(適用于單線程寫(xiě)、多線程讀的“happens-before”場(chǎng)景,如DCL單例模式)。volatile與synchronized的核心區(qū)別:原子性:volatile不保證原子性(如i++操作包含讀、改、寫(xiě)三步,非原子);synchronized通過(guò)鎖機(jī)制保證代碼塊的原子性。作用范圍:volatile用于修飾變量;synchronized用于修飾方法、代碼塊。鎖機(jī)制:volatile無(wú)鎖,不會(huì)導(dǎo)致線程阻塞;synchronized可能因鎖競(jìng)爭(zhēng)使線程進(jìn)入BLOCKED狀態(tài)??梢?jiàn)性與有序性:兩者均能保證可見(jiàn)性和有序性,但synchronized的覆蓋范圍更廣(通過(guò)Monitor保證整個(gè)代碼塊的同步)。Q:死鎖產(chǎn)生的條件是什么?如何避免和檢測(cè)死鎖?A:死鎖是指兩個(gè)或多個(gè)線程因互相等待對(duì)方持有的資源而無(wú)法繼續(xù)執(zhí)行的狀態(tài),其產(chǎn)生需同時(shí)滿足四個(gè)必要條件:1.互斥條件:資源同一時(shí)間只能被一個(gè)線程占用(如synchronized鎖)。2.持有并等待:線程已持有至少一個(gè)資源,同時(shí)請(qǐng)求其他線程持有的資源,且不釋放已持有的資源。3.不可搶占:線程持有的資源不能被其他線程強(qiáng)行搶占,只能由持有者主動(dòng)釋放。4.循環(huán)等待:線程間形成資源的環(huán)形等待鏈(如線程A等線程B的資源,線程B等線程A的資源)。避免死鎖的方法:破壞互斥條件:某些資源可改為共享訪問(wèn)(如使用無(wú)鎖數(shù)據(jù)結(jié)構(gòu)),但多數(shù)資源(如文件)本身具有互斥性,此方法適用場(chǎng)景有限。破壞持有并等待:要求線程一次性獲取所有需要的資源(如通過(guò)鎖排序,按固定順序獲取多個(gè)鎖)。破壞不可搶占:使用可搶占的鎖(如ReentrantLock的tryLock(longtime,TimeUnitunit)方法,超時(shí)后釋放已持有的鎖)。破壞循環(huán)等待:對(duì)資源進(jìn)行全局排序,所有線程按同一順序獲取資源(如線程A和B都先鎖資源1,再鎖資源2)。檢測(cè)死鎖的方法:jstack命令:通過(guò)“jstack<進(jìn)程ID>”提供線程轉(zhuǎn)儲(chǔ)文件,搜索“BLOCKED”狀態(tài)線程,查看其等待的鎖和持有鎖的線程,判斷是否存在循環(huán)等待。JConsole/JVisualVM:圖形化工具可直觀展示線程狀態(tài)和鎖競(jìng)爭(zhēng)關(guān)系,標(biāo)記死鎖線程。ThreadMXBean:通過(guò)編程方式調(diào)用ThreadMXBean.findDeadlockedThreads()獲取死鎖線程ID,實(shí)現(xiàn)自動(dòng)化檢測(cè)。Q:CAS(Compare-And-Swap)的原理是什么?存在哪些問(wèn)題?如何解決?A:CAS是一種無(wú)鎖的原子操作,其核心思想是“比較并交換”,具體步驟為:1.假設(shè)當(dāng)前內(nèi)存值為V,預(yù)期舊值為A,目標(biāo)新值為B。2.若V等于A(說(shuō)明未被其他線程修改),則將V更新為B,操作成功。3.若V不等于A(說(shuō)明已被其他線程修改),則操作失敗,可重試或放棄。CAS的底層依賴CPU的原子指令(如x86的cmpxchg)實(shí)現(xiàn),無(wú)需加鎖,因此在低競(jìng)爭(zhēng)場(chǎng)景下性能優(yōu)于synchronized。Java中通過(guò)sun.misc.Unsafe類(lèi)的compareAndSwapXXX()方法提供CAS操作(如AtomicInteger的incrementAndGet()方法基于CAS實(shí)現(xiàn))。CAS存在的三大問(wèn)題及解決方法:1.ABA問(wèn)題:線程1讀取V=A,準(zhǔn)備更新為B;此時(shí)線程2將V改為A(中間經(jīng)歷A→B→A),線程1的CAS操作仍會(huì)成功,但實(shí)際數(shù)據(jù)已被修改過(guò)。解決方法是使用帶版本號(hào)的原子類(lèi)(如AtomicStampedReference,存儲(chǔ)值和版本號(hào),比較時(shí)同時(shí)檢查值和版本)。2.循環(huán)時(shí)間長(zhǎng)開(kāi)銷(xiāo)大:高競(jìng)爭(zhēng)場(chǎng)景下,CAS可能多次重試仍失敗,導(dǎo)致CPU空轉(zhuǎn)。解決方法是限制重試次數(shù),或退化為鎖(如JDK1.8的ConcurrentHashMap在鏈表轉(zhuǎn)紅黑樹(shù)時(shí)使用synchronized)。3.只能保證單個(gè)變量的原子性:CAS僅能對(duì)單個(gè)變量進(jìn)行原子操作,對(duì)多個(gè)變量的同步需使用鎖或AtomicReference(將多個(gè)變量封裝為一個(gè)對(duì)象)。Q:AQS(AbstractQueuedSynchronizer)的核心設(shè)計(jì)思想是什么?如何通過(guò)AQS實(shí)現(xiàn)自定義同步器?A:AQS是Java并發(fā)包(java.util.concurrent)的基礎(chǔ)框架,用于構(gòu)建鎖(如ReentrantLock)和同步工具類(lèi)(如CountDownLatch)。其核心設(shè)計(jì)思想是通過(guò)一個(gè)volatile的state變量(表示同步狀態(tài),如鎖的重入次數(shù)、計(jì)數(shù)器值)和一個(gè)FIFO的同步隊(duì)列(存儲(chǔ)等待獲取鎖的線程),結(jié)合模板方法模式,將同步操作的通用邏輯(如線程入隊(duì)、喚醒)封裝,由子類(lèi)實(shí)現(xiàn)具體的同步規(guī)則(如state的獲取和釋放)。AQS的關(guān)鍵組件:state變量:通過(guò)getState()、setState()、compareAndSetState()方法原子操作,子類(lèi)需定義state的含義(如ReentrantLock中state表示鎖的重入次數(shù))。同步隊(duì)列:雙向鏈表結(jié)構(gòu),節(jié)點(diǎn)(Node)包含線程引用、等待狀態(tài)(如SIGNAL、CANCELLED),用于管理等待線程。條件隊(duì)列(可選):由ConditionObject實(shí)現(xiàn),每個(gè)Condition對(duì)應(yīng)一個(gè)單向鏈表隊(duì)列,用于線程等待特定條件(如ReentrantLock.newCondition())。自定義同步器的步驟:1.繼承AQS,重寫(xiě)tryAcquire(intarg)(獨(dú)占模式獲取鎖)或tryAcquireShared(intarg)(共享模式獲取鎖)方法,定義state的獲取邏輯(需保證原子性,通常使用CAS操作)。2.重寫(xiě)tryRelease(intarg)(獨(dú)占模式釋放鎖)或tryReleaseShared(intarg)(共享模式釋放鎖)方法,定義state的釋放邏輯。3.根據(jù)需求選擇獨(dú)占模式(如自定義鎖)或共享模式(如自定義信號(hào)量),通過(guò)acquire()/release()(獨(dú)占)或acquireShared()/releaseShared()(共享)方法調(diào)用模板方法,利用AQS的隊(duì)列管理功能。示例:實(shí)現(xiàn)一個(gè)簡(jiǎn)單的不可重入獨(dú)占鎖,state=0表示未鎖定,state=1表示鎖定。```javaclassSimpleLockextendsAbstractQueuedSynchronizer{//嘗試獲取鎖(獨(dú)占模式)@OverrideprotectedbooleantryAcquire(intarg){if(arg!=1)thrownewIllegalArgumentException("argmustbe1");returncompareAndSetState(0,1);//CAS設(shè)置state為1,成功則獲取鎖}//嘗試釋放鎖(獨(dú)占模式)@OverrideprotectedbooleantryRelease(intarg){if(arg!=1)thrownewIllegalArgumentException("argmustbe1");setState(0);//釋放鎖,直接設(shè)置state為0(無(wú)需CAS,因只有持有者能釋放)returntrue;}publicvoidlock(){acquire(1);//調(diào)用AQS的acquire模板方法}publicvoidunlock(){release(1);//調(diào)用AQS的release模板方法}}```Q:CountDownLatch、CyclicBarrier、Semaphore的區(qū)別和使用場(chǎng)景是什么?A:三者均為并發(fā)工具類(lèi),用于協(xié)調(diào)多線程執(zhí)行,但功能和適用場(chǎng)景不同:1.CountDownLatch:核心機(jī)制:內(nèi)部維護(hù)一個(gè)計(jì)數(shù)器(初始值為N),線程調(diào)用countDown()將計(jì)數(shù)器減1,調(diào)用await()的線程會(huì)阻塞直到計(jì)數(shù)器變?yōu)?。特點(diǎn):計(jì)數(shù)器只能使用一次(不可重置),適用于“等待多個(gè)任務(wù)完成”的場(chǎng)景(如主線程等待所有子線程完成初始化后開(kāi)始業(yè)務(wù)操作)。示例:```javaCountDownLatchlatch=newCountDownLatch(3);for(inti=0;i<3;i++){newThread(()->{//執(zhí)行任務(wù)latch.countDown();}).start();}latch.await();//主線程等待3個(gè)子線程完成```2.CyclicBarrier:核心機(jī)制:設(shè)置一個(gè)屏障點(diǎn)(初始Parties=N),線程調(diào)用await()后進(jìn)入等待,當(dāng)有N個(gè)線程到達(dá)屏障時(shí),屏障打開(kāi),所有線程繼續(xù)執(zhí)行(可選擇觸發(fā)一個(gè)Runnable回調(diào))。特點(diǎn):計(jì)數(shù)器可重復(fù)使用(reset()方法重置),適用于“多線程協(xié)作完成階段任務(wù)”的場(chǎng)景(如多個(gè)線程分階段處理數(shù)據(jù),每階段需所有線程完成后再進(jìn)入下一階段)。示例:```javaCyclicBarrierbarrier=newCyclicBarrier(3,()->System.out.println("階段完成"));for(inti=0;i<3;i++){newThread(()->{//階段1任務(wù)barrier.await();//階段2任務(wù)barrier.await();}).start();}```3.Semaphore:核心機(jī)制:維護(hù)一個(gè)許可證計(jì)數(shù)器(初始permits=N),線程調(diào)用acquire()獲取許可證(計(jì)數(shù)器減1,若為0則阻塞),調(diào)用release()釋放許可證(計(jì)數(shù)器加1)。特點(diǎn):控制同時(shí)訪問(wèn)資源的線程數(shù)(限流),適用于“資源池訪問(wèn)控制”的場(chǎng)景(如數(shù)據(jù)庫(kù)連接池最多允許10個(gè)線程同時(shí)獲取連接)。示例:```javaSemaphoresemaphore=newSemaphore(2);//允許2個(gè)線程同時(shí)訪問(wèn)for(inti=0;i<5;i++){newThread(()->{semaphore.acquire();try{//訪問(wèn)受限資源}finally{semaphore.release();}}).start();}```Q:線程間通信的方式有哪些?wait/notify和Condition的區(qū)別是什么?A:線程間通信指多個(gè)線程通過(guò)共享狀態(tài)或信號(hào)協(xié)調(diào)執(zhí)行順序,常見(jiàn)方式包括:1.共享變量:通過(guò)volatile或原子類(lèi)(如AtomicBoolean)標(biāo)記狀態(tài),線程輪詢檢查狀態(tài)變化(需結(jié)合鎖保證可見(jiàn)性)。2.wait/notify機(jī)制:基于Object類(lèi)的wait()、notify()、notifyAll()方法,需在synchronized塊中調(diào)用,通過(guò)Monitor的等待隊(duì)列實(shí)現(xiàn)通信。3.Condition接口:基于Lock的newCondition()方法獲取Condition對(duì)象,通過(guò)await()、signal()、signalAll()方法實(shí)現(xiàn)通信,支持多個(gè)等待隊(duì)列。4.管道流:通過(guò)PipedInputStream/PipedOutputStream在兩個(gè)線程間傳輸數(shù)據(jù)(適用于字節(jié)流或字符流通信)。5.并發(fā)工具類(lèi):如CountDownLatch、CyclicBarrier(前文已述),通過(guò)計(jì)數(shù)器或屏障協(xié)調(diào)線程。wait/notify與Condition的核心區(qū)別:所屬對(duì)象:wait/notify是Object類(lèi)的方法,依賴synchronized同步塊;Condition是java.util.concurrent.locks包下的接口,依賴Lock對(duì)象(如ReentrantLock)。等待隊(duì)列數(shù)量:一個(gè)Object對(duì)象僅對(duì)應(yīng)一個(gè)等待隊(duì)列;一個(gè)Lock可創(chuàng)建多個(gè)Condition對(duì)象,每個(gè)對(duì)應(yīng)獨(dú)立的等待隊(duì)列,支持精準(zhǔn)喚醒(如生產(chǎn)者-消費(fèi)者模型中,生產(chǎn)者喚醒消費(fèi)者,消費(fèi)者喚醒生產(chǎn)者)。喚醒靈活性:notify()隨機(jī)喚醒一個(gè)線程,notifyAll()喚醒所有線程;signal()喚醒指定Condition隊(duì)列中的一個(gè)線程,signalAll()喚醒所有線程,避免無(wú)效喚醒(如多個(gè)生產(chǎn)者等待同一條件時(shí),僅喚醒一個(gè))。超時(shí)和中斷支持:Condition的await(longtime,TimeUnitunit)支持超時(shí)等待,awaitInterruptibly()支持中斷響應(yīng);wait(longtimeout)雖支持超時(shí),但中斷響應(yīng)需捕獲InterruptedException。Q:Future和Callable的作用是什么?如何處理Future的異常?A:Future和Callable是Java并發(fā)包中用于處理異步任務(wù)的接口:Callable:與Runnable類(lèi)似,但可返回結(jié)果并拋出受檢異常。Runnable的run()方法無(wú)返回值,Callable的call()方法返回V類(lèi)型結(jié)果(需配合Future獲?。uture:表示異步任務(wù)的結(jié)果,提供方法檢查任務(wù)是否完成(isDone())、取消任務(wù)(cancel(booleanmayInterruptIfRunning))、獲取結(jié)果(get()/get(longtimeout,TimeUnitunit))。使用示例:```javaExecutorServiceexecutor=Executors.newSingleThreadExecutor();Future<Integer>future=executor.submit(()->{//submit接收Callableif(Math.random()<0.5)thrownewIOException("任務(wù)失敗");return42;});try{Integerresult=future.get();//阻塞直到任務(wù)完成或異常System.out.println("結(jié)果:"+result);}catch(InterruptedExceptione){Thread.currentThread().interrupt();//恢復(fù)中斷狀態(tài)}catch(ExecutionExceptione){Throwablecause=e.getCause();//獲取任務(wù)中的原始異常System.out.println("任務(wù)異常:"+cause.getMessage());}```處理Future異常的方法:1.get()方法捕獲ExecutionException:任務(wù)中的異常會(huì)被封裝為ExecutionException拋出,通過(guò)e.getCause()獲取原始異常(如IOException、RuntimeException)。2.使用CompletableFuture:Java8引入的CompletableFuture支持更靈活的異常處理,通過(guò)exceptionally()、handle()等方法異步處理異常,避免阻塞。例如:```javaCompletableFuture<Integer>future=CompletableFuture.supplyAsync(()->{thrownewRuntimeException("任務(wù)失敗");}).exceptionally(e->{System.out.println("處理異常:"+e.getMessage());return-1;//默認(rèn)值});```3.超時(shí)控制:調(diào)用get(longtimeout,TimeUnitunit)避免無(wú)限阻塞,超時(shí)后拋出TimeoutException,可結(jié)合重試邏輯處理。Q:ConcurrentHashMap在JDK1.7和JDK1.8中的實(shí)現(xiàn)差異有哪些?A:ConcurrentHashMap是線程安全的哈希表,JDK1.7和JDK1.8的實(shí)現(xiàn)差異主要體現(xiàn)在鎖機(jī)制和數(shù)據(jù)結(jié)構(gòu)上:JDK1.7版本:分段鎖(Segment):基于ReentrantLock的分段設(shè)計(jì),將哈希表分為多個(gè)Segment(默認(rèn)16個(gè)),每個(gè)Segment獨(dú)立加鎖,不同Segment的操作可并行。數(shù)據(jù)結(jié)構(gòu):每個(gè)Segment包含一個(gè)HashEntry數(shù)組(鏈表結(jié)構(gòu)),哈希沖突時(shí)通過(guò)鏈表解決。鎖粒度:對(duì)單個(gè)Segment加鎖,并發(fā)度為Segment的數(shù)量(默認(rèn)16),但調(diào)整并發(fā)度需重建整個(gè)結(jié)構(gòu)(不支持動(dòng)態(tài)擴(kuò)容)。JDK1.8版本:CAS+synchronized:取消Segment,采用Node數(shù)組+鏈表/紅黑樹(shù)的結(jié)構(gòu)。當(dāng)操作數(shù)組中的某個(gè)桶(Node)時(shí),僅對(duì)該桶的頭節(jié)點(diǎn)加synchronized鎖(鎖粒度更小,僅鎖一個(gè)節(jié)點(diǎn))。數(shù)據(jù)結(jié)構(gòu)優(yōu)化:當(dāng)鏈表長(zhǎng)度超過(guò)8且數(shù)組長(zhǎng)度≥64時(shí),鏈表轉(zhuǎn)換為紅黑樹(shù)(提高查找效率);當(dāng)紅黑樹(shù)節(jié)點(diǎn)數(shù)≤6時(shí),退化為鏈表。并發(fā)度提升:鎖粒度從Segment級(jí)別降至節(jié)點(diǎn)級(jí)別,并發(fā)度顯著提高(理論上為數(shù)組長(zhǎng)度)。動(dòng)態(tài)擴(kuò)容:采用“多線程協(xié)助擴(kuò)容”機(jī)制,當(dāng)某個(gè)線程觸發(fā)擴(kuò)容時(shí),其他線程參與遷移數(shù)據(jù)(通過(guò)sizeCtl變量標(biāo)記擴(kuò)容狀態(tài)),提升擴(kuò)容效率??偨Y(jié):JDK1.8的ConcurrentHashMap通過(guò)更細(xì)粒度的鎖(頭節(jié)點(diǎn)synchronized)、紅黑樹(shù)優(yōu)化和多線程擴(kuò)容,在高并發(fā)場(chǎng)景下性能優(yōu)于1.7的分段鎖實(shí)現(xiàn),同時(shí)簡(jiǎn)化了代碼結(jié)構(gòu)(移除了Segment類(lèi))。Q:什么是線程安全?常見(jiàn)的線程安全實(shí)現(xiàn)方式有哪些?A:線程安全指多個(gè)線程并發(fā)訪問(wèn)某個(gè)對(duì)象或方法時(shí),無(wú)論操作系統(tǒng)如何調(diào)度線程、如何交替執(zhí)行,對(duì)象的狀態(tài)始終保持一致,且執(zhí)行結(jié)果與單線程執(zhí)行結(jié)果一致。線程不安全的典型場(chǎng)景包括:多個(gè)線程同時(shí)修改共享變量(如i++)、未正確同步的共享對(duì)象狀態(tài)訪問(wèn)等。常見(jiàn)的線程安全實(shí)現(xiàn)方式:1.不可變對(duì)象:對(duì)象創(chuàng)建后狀態(tài)不可修改(如String、Integer),通過(guò)final關(guān)鍵字修飾字段,避免并發(fā)修改風(fēng)險(xiǎn)。例如:```javaclassImmutableUser{privatefinalStringname;publicImmutableUser(Stringname){=name;}publicStringgetName(){returnname;}//無(wú)修改方法}```2.線程封閉:將數(shù)據(jù)限制在單個(gè)線程內(nèi)訪問(wèn),避免共享。常見(jiàn)方式:棧封閉:數(shù)據(jù)作為局部變量(如方法內(nèi)的對(duì)象),僅被當(dāng)前線程訪問(wèn)。ThreadLocal:通過(guò)ThreadLocal存儲(chǔ)數(shù)據(jù),每個(gè)線程有獨(dú)立的副本(如數(shù)據(jù)庫(kù)連接的線程本地存儲(chǔ))。3.同步控制:通過(guò)鎖或原子操作保證共享數(shù)據(jù)的原子性、可見(jiàn)性和有序性:顯式鎖:ReentrantLock、ReentrantReadWriteLock(讀寫(xiě)鎖分離,讀鎖共享、寫(xiě)鎖獨(dú)占)。隱式鎖:synchronized關(guān)鍵字(修飾方法或代碼塊)。原子類(lèi):java.util.concurrent.atomic包下的類(lèi)(如AtomicInteger、AtomicReference),基于CAS實(shí)現(xiàn)原子操作。4.并發(fā)容器:使用線程安全的容器類(lèi)(如ConcurrentHashMap、CopyOnWriteArrayList),內(nèi)部已封裝同步邏輯,無(wú)需額外加鎖。例如,CopyOnWriteArrayList在寫(xiě)操作時(shí)復(fù)制數(shù)組,讀操作無(wú)鎖,適用于讀多寫(xiě)少場(chǎng)景。Q:如何分析和定位多線程程序中的性能瓶頸?A:多線程程序的性能瓶頸通常源于鎖競(jìng)爭(zhēng)、線程上下文切換、內(nèi)存可見(jiàn)性問(wèn)題或資源爭(zhēng)用,可通過(guò)以下步驟分析和定位:1.監(jiān)控線程狀態(tài):使用JDK工具(如jstack、JConsole、JVisualVM)查看線程狀態(tài)(RUNNABLE、BLOCKED、WAITING),統(tǒng)計(jì)阻塞線程比例。若大量線程處于BLOCKED狀態(tài),可能存在鎖競(jìng)爭(zhēng)(如synchroniz
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年黑龍江旅游職業(yè)技術(shù)學(xué)院?jiǎn)握芯C合素質(zhì)考試模擬試題帶答案解析
- 2026年貴州裝備制造職業(yè)學(xué)院高職單招職業(yè)適應(yīng)性測(cè)試備考試題有答案解析
- 2026年河南工業(yè)和信息化職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)考試模擬試題帶答案解析
- 2026年長(zhǎng)沙南方職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)筆試備考題庫(kù)附答案詳解
- 2026年安徽國(guó)際商務(wù)職業(yè)學(xué)院高職單招職業(yè)適應(yīng)性考試模擬試題帶答案解析
- 2026年福州科技職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能考試參考題庫(kù)帶答案解析
- 投資合作協(xié)議合同協(xié)議(2025年)
- 2026年鶴壁職業(yè)技術(shù)學(xué)院?jiǎn)握芯C合素質(zhì)筆試模擬試題帶答案解析
- 2026年河南工業(yè)和信息化職業(yè)學(xué)院?jiǎn)握芯C合素質(zhì)筆試模擬試題帶答案解析
- 2026年河南經(jīng)貿(mào)職業(yè)學(xué)院高職單招職業(yè)適應(yīng)性測(cè)試備考試題有答案解析
- 2025年學(xué)校食堂從業(yè)人員食品安全知識(shí)培訓(xùn)考試試題(附答案)
- 2025年建筑信息化行業(yè)分析報(bào)告及未來(lái)五至十年行業(yè)發(fā)展報(bào)告
- 建筑防欠薪管理制度
- 中國(guó)共產(chǎn)主義青年團(tuán)紀(jì)律處分條例試行解讀學(xué)習(xí)
- 2025年廣東省深圳市中考英語(yǔ)復(fù)習(xí)聽(tīng)說(shuō)題型課件信息復(fù)述提問(wèn)
- 咖啡消費(fèi)人群的細(xì)分與定位-全面剖析
- 09.品質(zhì)月報(bào)統(tǒng)計(jì)表模板
- 2024-2025學(xué)年北京朝陽(yáng)區(qū)九年級(jí)初三(上)期末歷史試卷(含答案)
- DB11T 354-2023 生活垃圾收集運(yùn)輸管理規(guī)范
- 赤石特大橋施工安全風(fēng)險(xiǎn)評(píng)估報(bào)告
- QBT 2770-2006 羽毛球拍行業(yè)標(biāo)準(zhǔn)
評(píng)論
0/150
提交評(píng)論