Lock接口提供比synchronized更靈活的鎖控制,支持嘗試獲取、可中斷、超時(shí)獲取和公平鎖;2. Condition允許通過(guò)多個(gè)條件變量實(shí)現(xiàn)精確的線(xiàn)程間通信,避免虛假喚醒;3. 常見(jiàn)Synchronizers包括CountDownLatch用于等待多個(gè)任務(wù)完成、CyclicBarrier用于多線(xiàn)程同步到達(dá)屏障點(diǎn)、Semaphore用于控制并發(fā)線(xiàn)程數(shù)、Phaser用于動(dòng)態(tài)線(xiàn)程數(shù)的分階段同步;使用時(shí)需優(yōu)先考慮synchronized的簡(jiǎn)潔性,Lock必須結(jié)合try-finally防止死鎖,Condition應(yīng)配合while使用,且應(yīng)根據(jù)場(chǎng)景選擇合適的同步工具以避免過(guò)度設(shè)計(jì)。
在 Java 并發(fā)編程中,synchronized
關(guān)鍵字雖然簡(jiǎn)單易用,但在更復(fù)雜的場(chǎng)景下顯得不夠靈活。為此,Java 提供了 java.util.concurrent.locks
包,其中包含更強(qiáng)大的并發(fā)控制工具:Locks、Conditions 和 Synchronizers。它們讓開(kāi)發(fā)者能更精細(xì)地控制線(xiàn)程同步行為。

1. Lock 接口:比 synchronized 更靈活的鎖機(jī)制
Lock
是 synchronized
的增強(qiáng)替代方案,主要優(yōu)勢(shì)在于:
- 可以嘗試獲取鎖(
tryLock()
),避免阻塞 - 可以中斷等待鎖的線(xiàn)程
- 可以超時(shí)獲取鎖
- 更精細(xì)的鎖控制(如讀寫(xiě)分離)
常見(jiàn)實(shí)現(xiàn)類(lèi):ReentrantLock
Lock lock = new ReentrantLock(); lock.lock(); try { // 臨界區(qū) System.out.println("線(xiàn)程進(jìn)入臨界區(qū)"); } finally { lock.unlock(); // 必須放在 finally 中,防止死鎖 }
?? 注意:必須手動(dòng)釋放鎖,否則會(huì)導(dǎo)致死鎖或資源泄漏。
與 synchronized 的對(duì)比
特性 | synchronized | ReentrantLock |
---|---|---|
自動(dòng)釋放鎖 | 是 | 否(需手動(dòng) unlock) |
嘗試非阻塞獲取鎖 | 否 | 是(tryLock) |
可中斷等待鎖 | 否 | 是(lockInterruptibly) |
超時(shí)獲取鎖 | 否 | 是(tryLock(timeout)) |
公平鎖支持 | 否 | 是(構(gòu)造時(shí)指定) |
2. Condition:線(xiàn)程間通信的精確控制
Condition
類(lèi)似于 Object
的 wait()
和 notify()
,但更靈活。一個(gè) Lock
可以創(chuàng)建多個(gè) Condition
實(shí)例,實(shí)現(xiàn)多路等待/通知。
使用場(chǎng)景:生產(chǎn)者-消費(fèi)者模型
Lock lock = new ReentrantLock(); Condition notFull = lock.newCondition(); Condition notEmpty = lock.newCondition(); // 生產(chǎn)者 lock.lock(); try { while (queue.size() == CAPACITY) { notFull.await(); // 等待隊(duì)列不滿(mǎn) } queue.add(item); notEmpty.signal(); // 通知消費(fèi)者 } finally { lock.unlock(); } // 消費(fèi)者 lock.lock(); try { while (queue.isEmpty()) { notEmpty.await(); // 等待隊(duì)列不空 } String item = queue.poll(); notFull.signal(); // 通知生產(chǎn)者 } finally { lock.unlock(); }
? 優(yōu)勢(shì):多個(gè)條件變量可獨(dú)立控制,避免虛假喚醒或通知錯(cuò)亂。
3. 常見(jiàn) Synchronizers:JUC 提供的高級(jí)同步工具
Java 提供了幾種開(kāi)箱即用的同步輔助類(lèi),位于 java.util.concurrent
包中:
① CountDownLatch:倒計(jì)時(shí)門(mén)閂
用于讓一個(gè)或多個(gè)線(xiàn)程等待其他線(xiàn)程完成操作。
CountDownLatch latch = new CountDownLatch(3); // 工作線(xiàn)程 latch.countDown(); // 等待線(xiàn)程 latch.await(); // 阻塞直到計(jì)數(shù)歸零
? 適用場(chǎng)景:主線(xiàn)程等待多個(gè)后臺(tái)任務(wù)完成。
② CyclicBarrier:循環(huán)柵欄
讓一組線(xiàn)程互相等待,直到全部到達(dá)某個(gè)屏障點(diǎn),再一起繼續(xù)執(zhí)行。
CyclicBarrier barrier = new CyclicBarrier(3, () -> { System.out.println("所有線(xiàn)程已就位,開(kāi)始行動(dòng)!"); }); barrier.await(); // 每個(gè)線(xiàn)程調(diào)用后等待
? 適用場(chǎng)景:多線(xiàn)程并行計(jì)算分階段同步,如并行測(cè)試數(shù)據(jù)準(zhǔn)備。
③ Semaphore:信號(hào)量,控制并發(fā)數(shù)量
限制同時(shí)訪問(wèn)某資源的線(xiàn)程數(shù)(如數(shù)據(jù)庫(kù)連接池)。
Semaphore semaphore = new Semaphore(3); // 最多3個(gè)線(xiàn)程訪問(wèn) semaphore.acquire(); // 獲取許可 try { // 執(zhí)行受限操作 } finally { semaphore.release(); // 釋放許可 }
? 適用場(chǎng)景:限流、資源池控制。
④ Phaser:更靈活的同步屏障(進(jìn)階)
支持動(dòng)態(tài)注冊(cè)參與線(xiàn)程,適合分階段任務(wù)且線(xiàn)程數(shù)不固定的場(chǎng)景。
使用建議與注意事項(xiàng)
-
優(yōu)先使用 synchronized:如果場(chǎng)景簡(jiǎn)單,
synchronized
更安全、簡(jiǎn)潔。 - Lock 必須配 try-finally:防止異常導(dǎo)致鎖無(wú)法釋放。
- 避免嵌套鎖:容易引發(fā)死鎖,若必須使用,注意加鎖順序。
- Condition 要配合 while 判斷:防止虛假喚醒。
- Synchronizers 不是萬(wàn)能:選擇合適的工具,避免過(guò)度設(shè)計(jì)。
基本上就這些。Java 的并發(fā)工具從底層 Lock
到高層 Synchronizers
,提供了豐富的選擇。關(guān)鍵是理解每種機(jī)制的適用場(chǎng)景,避免“會(huì)用但用錯(cuò)”。
以上是Java并發(fā):鎖,條件和同步器的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線(xiàn)人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門(mén)文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)代碼編輯軟件(SublimeText3)

Java中的枚舉(enum)是一種特殊的類(lèi),用于表示固定數(shù)量的常量值。1.使用enum關(guān)鍵字定義;2.每個(gè)枚舉值都是該枚舉類(lèi)型的公共靜態(tài)最終實(shí)例;3.可以包含字段、構(gòu)造函數(shù)和方法,為每個(gè)常量添加行為;4.可在switch語(yǔ)句中使用,支持直接比較,并提供name()、ordinal()、values()和valueOf()等內(nèi)置方法;5.枚舉可提升代碼的類(lèi)型安全性、可讀性和靈活性,適用于狀態(tài)碼、顏色或星期等有限集合場(chǎng)景。

接口隔離原則(ISP)要求不強(qiáng)制客戶(hù)端依賴(lài)未使用的接口。其核心是用多個(gè)小而精的接口替代大而全的接口。違反該原則的表現(xiàn)包括:類(lèi)實(shí)現(xiàn)接口時(shí)拋出未實(shí)現(xiàn)異常、存在大量無(wú)效方法實(shí)現(xiàn)、無(wú)關(guān)功能被強(qiáng)行歸入同一接口。應(yīng)用方法包括:按常用方法組劃分接口、依據(jù)客戶(hù)端使用拆分接口、必要時(shí)使用組合替代多接口實(shí)現(xiàn)。例如將包含打印、掃描、傳真方法的Machine接口拆分為Printer、Scanner和FaxMachine。在小型項(xiàng)目或所有客戶(hù)端均使用全部方法時(shí)可適當(dāng)放寬規(guī)則。

Java支持異步編程的方式包括使用CompletableFuture、響應(yīng)式流(如ProjectReactor)以及Java19 中的虛擬線(xiàn)程。1.CompletableFuture通過(guò)鏈?zhǔn)秸{(diào)用提升代碼可讀性和維護(hù)性,支持任務(wù)編排和異常處理;2.ProjectReactor提供Mono和Flux類(lèi)型實(shí)現(xiàn)響應(yīng)式編程,具備背壓機(jī)制和豐富的操作符;3.虛擬線(xiàn)程減少并發(fā)成本,適用于I/O密集型任務(wù),與傳統(tǒng)平臺(tái)線(xiàn)程相比更輕量且易于擴(kuò)展。每種方式均有適用場(chǎng)景,應(yīng)根據(jù)需求選擇合適工具并避免混合模型以保持簡(jiǎn)潔性

Callable和Runnable在Java中主要有三點(diǎn)區(qū)別。第一,Callable的call()方法可以返回結(jié)果,適合需要返回值的任務(wù),如Callable;而Runnable的run()方法無(wú)返回值,適用于無(wú)需返回的任務(wù),如日志記錄。第二,Callable允許拋出checked異常,便于錯(cuò)誤傳遞;而Runnable必須在內(nèi)部處理異常。第三,Runnable可直接傳給Thread或ExecutorService,而Callable只能提交給ExecutorService,并返回Future對(duì)象以

在Java中,枚舉(enum)適合表示固定常量集合,最佳實(shí)踐包括:1.用enum表示固定狀態(tài)或選項(xiàng),提升類(lèi)型安全和可讀性;2.為枚舉添加屬性和方法以增強(qiáng)靈活性,如定義字段、構(gòu)造函數(shù)、輔助方法等;3.使用EnumMap和EnumSet提高性能和類(lèi)型安全性,因其基于數(shù)組實(shí)現(xiàn)更高效;4.避免濫用enum,如動(dòng)態(tài)值、頻繁變更或復(fù)雜邏輯場(chǎng)景應(yīng)使用其他方式替代。正確使用enum能提升代碼質(zhì)量并減少錯(cuò)誤,但需注意其適用邊界。

JavaNIO是Java1.4引入的新型IOAPI,1)面向緩沖區(qū)和通道,2)包含Buffer、Channel和Selector核心組件,3)支持非阻塞模式,4)相比傳統(tǒng)IO更高效處理并發(fā)連接。其優(yōu)勢(shì)體現(xiàn)在:1)非阻塞IO減少線(xiàn)程開(kāi)銷(xiāo),2)Buffer提升數(shù)據(jù)傳輸效率,3)Selector實(shí)現(xiàn)多路復(fù)用,4)內(nèi)存映射加快文件讀寫(xiě)。使用時(shí)需注意:1)Buffer的flip/clear操作易混淆,2)非阻塞下需手動(dòng)處理不完整數(shù)據(jù),3)Selector注冊(cè)需及時(shí)取消,4)NIO并非適用于所有場(chǎng)景。

Javaprovidesmultiplesynchronizationtoolsforthreadsafety.1.synchronizedblocksensuremutualexclusionbylockingmethodsorspecificcodesections.2.ReentrantLockoffersadvancedcontrol,includingtryLockandfairnesspolicies.3.Conditionvariablesallowthreadstowaitfor

Java的類(lèi)加載機(jī)制通過(guò)ClassLoader實(shí)現(xiàn),其核心工作流程分為加載、鏈接和初始化三個(gè)階段。加載階段由ClassLoader動(dòng)態(tài)讀取類(lèi)的字節(jié)碼并創(chuàng)建Class對(duì)象;鏈接包括驗(yàn)證類(lèi)的正確性、為靜態(tài)變量分配內(nèi)存及解析符號(hào)引用;初始化則執(zhí)行靜態(tài)代碼塊和靜態(tài)變量賦值。類(lèi)加載采用雙親委派模型,優(yōu)先委托父類(lèi)加載器查找類(lèi),依次嘗試Bootstrap、Extension和ApplicationClassLoader,確保核心類(lèi)庫(kù)安全且避免重復(fù)加載。開(kāi)發(fā)者可自定義ClassLoader,如URLClassL
