Java中synchronized與Lock的詳細(xì)對(duì)比
前言
在之前的面試中遇到過(guò)這樣一個(gè)問(wèn)題,synchronized和lock的對(duì)比,只回到了4個(gè)區(qū)別特性,記錄一下。
synchronized和Lock都是Java中用于實(shí)現(xiàn)線程同步的機(jī)制,但它們?cè)趯?shí)現(xiàn)方式、功能和性能上有顯著差異。以下是兩者的詳細(xì)對(duì)比:
1. 基本特性對(duì)比
| 特性 | synchronized | Lock (ReentrantLock) |
|---|---|---|
| 實(shí)現(xiàn)方式 | Java關(guān)鍵字,JVM層面實(shí)現(xiàn) | Java類,API層面實(shí)現(xiàn) |
| 獲取與釋放 | 自動(dòng)獲取和釋放鎖 | 需要手動(dòng)調(diào)用lock()和unlock() |
| 鎖的類型 | 非公平鎖 | 可選擇公平鎖或非公平鎖 |
| 可中斷性 | 不可中斷 | 可中斷(lockInterruptibly()) |
| 嘗試獲取鎖 | 不支持 | 支持(tryLock()) |
| 超時(shí)機(jī)制 | 不支持 | 支持(tryLock(time, unit)) |
| 條件變量 | 只能有一個(gè)條件隊(duì)列 | 可創(chuàng)建多個(gè)Condition對(duì)象 |
| 性能 | JDK6后優(yōu)化,性能接近 | 高競(jìng)爭(zhēng)下性能可能更好 |
2. 詳細(xì)比較
2.1 使用方式
synchronized:
public synchronized void method() {
// 同步代碼
}
// 或
public void method() {
synchronized(this) {
// 同步代碼塊
}
}Lock:
private Lock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
// 同步代碼
} finally {
lock.unlock();
}
}2.2 高級(jí)功能
Lock提供而synchronized不具備的功能:
嘗試非阻塞獲取鎖:
tryLock()可中斷的獲取鎖:
lockInterruptibly()超時(shí)獲取鎖:
tryLock(long time, TimeUnit unit)公平鎖:
new ReentrantLock(true)多個(gè)條件變量:
newCondition()
2.3 性能考慮
在低競(jìng)爭(zhēng)情況下,
synchronized性能與Lock相當(dāng)在高競(jìng)爭(zhēng)情況下,
Lock通常表現(xiàn)更好synchronized有優(yōu)化空間(鎖升級(jí):偏向鎖→輕量級(jí)鎖→重量級(jí)鎖)Lock需要手動(dòng)釋放鎖,容易忘記導(dǎo)致死鎖內(nèi)存占用
synchronized通常更節(jié)省內(nèi)存(特別是無(wú)競(jìng)爭(zhēng)時(shí));Lock需要額外對(duì)象來(lái)維護(hù)狀態(tài)和隊(duì)列
2.4 擴(kuò)展性
Lock的等待隊(duì)列實(shí)現(xiàn)更適合大量線程競(jìng)爭(zhēng)synchronized的Monitor在大量線程競(jìng)爭(zhēng)時(shí)可能成為瓶頸
2.5 選擇建議
使用synchronized的情況:
簡(jiǎn)單的同步需求
不需要高級(jí)功能
希望代碼更簡(jiǎn)潔
鎖的獲取和釋放在一個(gè)方法內(nèi)完成
使用Lock的情況:
需要高級(jí)功能(可中斷、超時(shí)、嘗試獲取等)
需要公平鎖
需要多個(gè)條件變量
鎖需要在多個(gè)方法間傳遞和釋放
高競(jìng)爭(zhēng)環(huán)境下對(duì)性能有更高要求
3. 示例對(duì)比
3.1 可中斷鎖示例
使用Lock:
Lock lock = new ReentrantLock();
try {
lock.lockInterruptibly();
// 同步代碼
} catch (InterruptedException e) {
// 處理中斷
} finally {
lock.unlock();
}synchronized無(wú)法實(shí)現(xiàn)可中斷鎖
3.2 嘗試獲取鎖示例
使用Lock:
if (lock.tryLock()) {
try {
// 獲取鎖成功
} finally {
lock.unlock();
}
} else {
// 獲取鎖失敗
}synchronized無(wú)法實(shí)現(xiàn)嘗試獲取鎖
4. 總結(jié)
synchronized是Java內(nèi)置的同步機(jī)制,使用簡(jiǎn)單但功能有限;Lock提供了更豐富的功能但需要手動(dòng)管理。在大多數(shù)情況下,synchronized已經(jīng)足夠,只有在需要其不具備的高級(jí)功能時(shí),才應(yīng)考慮使用Lock。
到此這篇關(guān)于Java中synchronized與Lock詳細(xì)對(duì)比的文章就介紹到這了,更多相關(guān)Java synchronized與Lock對(duì)比內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)RabbitMQ三種使用方式
本文主要介紹了SpringBoot實(shí)現(xiàn)RabbitMQ三種使用方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
SpringBoot中處理JSON的三大庫(kù)應(yīng)用全指南
在 Spring Boot 開發(fā)中,JSON 作為數(shù)據(jù)交互的通用格式,其處理效率與準(zhǔn)確性直接影響系統(tǒng)性能與用戶體驗(yàn),本文將全面對(duì)比SpringBoot處理JSON三大庫(kù)的特性,希望對(duì)大家有所幫助2025-07-07
feign 如何獲取請(qǐng)求真實(shí)目的ip地址
這篇文章主要介紹了feign 獲取請(qǐng)求真實(shí)目的ip地址操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
如何使用Spring?integration在Springboot中集成Mqtt詳解
MQTT是多個(gè)客戶端通過(guò)一個(gè)中央服務(wù)器傳遞信息的多對(duì)多協(xié)議,能高效地將信息分發(fā)給一個(gè)或多個(gè)訂閱者,下面這篇文章主要給大家介紹了關(guān)于如何使用Spring?integration在Springboot中集成Mqtt的相關(guān)資料,需要的朋友可以參考下2023-02-02
Spring?boot?CommandLineRunner啟動(dòng)任務(wù)傳參實(shí)例詳解
在使用SpringBoot構(gòu)建項(xiàng)目時(shí),我們通常有一些預(yù)先數(shù)據(jù)的加載,下面這篇文章主要給大家介紹了關(guān)于Spring?boot?CommandLineRunner啟動(dòng)任務(wù)傳參的相關(guān)資料,需要的朋友可以參考下2022-06-06
MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報(bào)錯(cuò)信息處理方案
這篇文章主要介紹了MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報(bào)錯(cuò)信息處理方案,分別介紹了兩種占位符的區(qū)別,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
解決mysql字符串類型的數(shù)字排序出錯(cuò):cast(year as signed)
這篇文章主要介紹了解決mysql字符串類型的數(shù)字排序出錯(cuò)問(wèn)題 :cast(year as signed),如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
spring boot和spring cloud之間的版本關(guān)系
這篇文章主要介紹了spring boot和spring cloud之間的版本關(guān)系,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08

