Java 鎖機制全面解析

在 Java 并發編程中,鎖(Lock)是保證線程安全的關鍵工具。本文將全面介紹 Java 的鎖機制,包括 synchronized 關鍵字、Lock 接口及其實現、讀寫鎖、樂觀鎖與悲觀鎖等,幫助新手理解 Java 并發控制。

1. Java 中的鎖概述

鎖(Lock)用于控制多個線程對共享資源的訪問。不同的鎖機制可以提供不同的性能、可重入性、公平性和可中斷性等特性。

2. synchronized 關鍵字

synchronized 是 Java 內置的同步機制,依賴于 Java 虛擬機(JVM)實現。

2.1 用法示例

public class SynchronizedExample {private int count = 0;public synchronized void increment() {count++;}
}

在上述示例中,increment 方法是同步方法,多個線程調用時會自動加鎖,保證 count 變量的線程安全。

2.2 synchronized 作用范圍

  • 同步實例方法:鎖住當前實例(this)。
  • 同步靜態方法:鎖住類對象(Class)。
  • 同步代碼塊:可以鎖定特定對象,提高并發性。
public void method() {synchronized (this) {// 代碼塊}
}

2.3 synchronized 的特性

  • 可重入性:一個線程獲取鎖后可以多次進入同步代碼。
  • 不可中斷:線程獲取鎖后,其他線程只能等待。
  • JVM 層面實現:使用 monitorentermonitorexit 指令。

3. Lock 接口(顯式鎖)

Lock 接口提供比 synchronized 更靈活的鎖控制,主要實現類是 ReentrantLock

3.1 ReentrantLock 用法

import java.util.concurrent.locks.ReentrantLock;public class LockExample {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}
}

3.2 ReentrantLock 特性

  • 可重入性:和 synchronized 類似,一個線程可以多次獲得相同的鎖。
  • 可中斷:支持 lockInterruptibly() 方法,中斷等待鎖的線程。
  • 公平鎖和非公平鎖:默認非公平鎖,可選擇公平鎖保證線程按請求順序獲取鎖。
ReentrantLock fairLock = new ReentrantLock(true); // 公平鎖

4. ReadWriteLock(讀寫鎖)

ReadWriteLock 提供讀鎖(多個線程可讀)和寫鎖(獨占)。

import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();private int data = 0;public int read() {lock.readLock().lock();try {return data;} finally {lock.readLock().unlock();}}public void write(int value) {lock.writeLock().lock();try {data = value;} finally {lock.writeLock().unlock();}}
}

5. 樂觀鎖與悲觀鎖

5.1 悲觀鎖

認為競爭嚴重,每次訪問資源都加鎖(synchronizedLock)。

5.2 樂觀鎖

認為競爭較少,使用 CAS(Compare And Swap) 機制,比如 AtomicInteger

import java.util.concurrent.atomic.AtomicInteger;public class AtomicExample {private final AtomicInteger count = new AtomicInteger(0);public void increment() {count.incrementAndGet();}
}

6. StampedLock(改進的讀寫鎖)

StampedLock 提供樂觀讀鎖,提高并發性能。

import java.util.concurrent.locks.StampedLock;public class StampedLockExample {private final StampedLock lock = new StampedLock();private int data = 0;public int read() {long stamp = lock.tryOptimisticRead();int currentData = data;if (!lock.validate(stamp)) { // 檢測數據是否被修改lock.readLock();try {currentData = data;} finally {lock.unlockRead(stamp);}}return currentData;}
}

7. ThreadLocal 變量

ThreadLocal 不是鎖,而是讓每個線程擁有自己的變量副本,避免鎖競爭。

public class ThreadLocalExample {private static final ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);public void increment() {threadLocal.set(threadLocal.get() + 1);}
}

8. 選擇合適的鎖

鎖類型特性適用場景
synchronizedJVM 層面,簡單易用適合簡單同步需求
ReentrantLock可中斷、支持公平鎖適合需要高級控制的場景
ReadWriteLock讀寫分離,提高并發讀多寫少的情況
StampedLock樂觀讀,提高性能適合高并發讀的場景
ThreadLocal線程私有,無鎖線程隔離數據

9. 總結

Java 提供了多種鎖機制,每種鎖都有其適用場景。synchronized 適用于簡單同步,Lock 提供更多控制,ReadWriteLock 適用于讀多寫少的情況,StampedLock 提供樂觀讀鎖以提高并發性能。此外,ThreadLocal 可用于無鎖并發,避免數據競爭。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73012.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73012.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73012.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaScript 中 “new Map()”的使用

new Map() 是 JavaScript 中用于創建 Map 對象 的構造函數。Map 是一種鍵值對集合&#xff0c;類似于普通對象&#xff08;Object&#xff09;&#xff0c;但有以下區別&#xff1a; 1. Map 的特點 1.1 鍵的類型 Map&#xff1a;鍵可以是任意類型&#xff08;包括對象、函數、…

Rust語言的集成測試

Rust語言的集成測試 引言 隨著軟件開發的不斷發展&#xff0c;測試已成為一個不可或缺的環節。特別是在系統復雜度日益增加的今天&#xff0c;確保代碼質量和穩定性變得尤為重要。Rust作為一門強調安全性和性能的編程語言&#xff0c;其測試框架提供了豐富的工具來幫助開發者…

手寫簡單的Spring基于注解配置的程序

需求說明&#xff1a; 自己寫一個簡單的 Spring 容器, 通過讀取類的注解(Component ControllerService Reponsitory) &#xff0c;將對象注入到 IOC 容器&#xff0c;自己使用 IOAnnotaion反射集合 技術實現 思路分析&#xff1a; 一、新建一個包component并在包下創建bean類 …

WSL 導入完整系統包教程

作者&#xff1a; DWDROME 配置環境&#xff1a; OS: Ubuntu 20.04.6 LTS on Windows 11 x86_64Kernel: 5.15.167.4-microsoft-standard-WSL2ros-noetic &#x1f9ed;WSL 導入完整系統包教程 ? 一、準備導出文件 假設你已有一個 .tar 的完整系統包&#xff08;如從 WSL 或 L…

使用selenium來獲取數據集

使用selenium來獲取數據集 1、下載最新的chrome瀏覽器與chromedriver.exe 查看chrome的版本,打開谷歌瀏覽器,點擊右上角的三個點,然后點擊【幫助】, 點擊【關于Google Chrome】 然后去下載同樣為134版本號的chromedriver.exe, 網址:https://googlechromelabs.github.…

(二)VMware:VMware虛擬機安裝CentOS教程

目錄 1、準備CentOS 7鏡像1.1、官網鏡像下載1.2、清華大學開源鏡像下載?1.3、阿里云開源鏡像下載 2、使用 VMware安裝CentOS 72.1、創建虛擬機2.2、選擇自定義安裝2.3、硬件兼容性&#xff0c;保持默認2.4、選擇下載的ISO鏡像2.5、設置虛擬機名稱以及存放磁盤位置2.6、按照需求…

【Agent】Dify Docker 安裝問題 INTERNAL SERVER ERROR

總結&#xff1a;建議大家選擇穩定版本的分支&#xff0c;直接拉取 master 分支&#xff0c;可能出現一下后面更新代碼導致缺失一些環境內容。 啟動報錯 一直停留在 INSTALL 界面 我是通過 Docker 進行安裝的&#xff0c;由于項目開發者不嚴謹導致&#xff0c;遇到一個奇怪的…

MySQL -- 復合查詢

數據庫的查詢是數據庫使用中比較重要的環節&#xff0c;前面的基礎查詢比較簡單&#xff0c;不做介紹&#xff0c;可自行查閱。本文主要介紹復合查詢&#xff0c;并結合用例進行講解。 本文的用例依據Soctt模式的經典測試表&#xff0c;可以自行下載&#xff0c;也可以自己創建…

flutter 開發web端的性能優化

參考資料 Flutter for Web 首次首屏優化 ——JS 分片優化_main.dart.js-CSDN博客文章瀏覽閱讀1.4k次。本文介紹了如何通過延遲加載組件和js分片優化Flutter for Web應用的加載速度。在實踐中&#xff0c;通過按需加載減少js文件大小&#xff0c;使用并行加載提升加載效率。通過…

編譯安裝redis,systemtcl配置redis自啟動,系統并發調優

編譯安裝redis&#xff0c;systemtcl配置redis自啟動&#xff0c;系統并發調優 1、編譯安裝redis wget https://download.redis.io/releases/redis-7.4.2.tar.gz tar -zxf redis-7.4.2.tar.gz cd redis-7.4.2/ make make install/usr/local/bin/redis-server -v2、systemtcl配…

firefly經典藍牙和QProcess、QFileSystemWatcher記錄

QProcess 默認不會啟動一個 shell 來解析命令,而是直接調用操作系統的系統調用來啟動外部程序。也就是通過fork一個子線程或者exec一個子進程來執行命令。 QProcess的參數模式 QProcess 需要明確指定命令的可執行文件路徑或參數列表。 如果命令是一個可執行文件的路徑…

Java定時任務的三重境界:從單機心跳到分布式協調

《Java定時任務的三重境界&#xff1a;從單機心跳到分布式協調》 本文將以生產級代碼標準&#xff0c;揭秘Java定時任務從基礎API到分布式調度的6種實現范式&#xff0c;深入剖析ScheduledThreadPoolExecutor與Quartz Scheduler的線程模型差異&#xff0c;并給出各方案的性能壓…

QT QML實現音頻波形圖進度條,可點擊定位或拖動進度

前言 本項目實現了使用QT QML創建一個音頻波形圖進度條的功能。用戶可以在界面上看到音頻波形圖&#xff0c;并且可以點擊進度條上的位置進行定位&#xff0c;也可以拖動進度條來調整播放進度。可以讓用戶更方便地控制音頻的播放進度&#xff0c;并且通過音頻波形圖可以直觀地…

高速網絡包處理,基礎網絡協議上內核態直接處理數據包,XDP技術的原理

文章目錄 預備知識TCP/IP 網絡模型&#xff08;4層、7層&#xff09;iptables/netfilterlinux網絡為什么慢 DPDKXDPBFPeBPFXDPXDP 程序典型執行流通過網絡協議棧的入包XDP 組成 使用 GO 編寫 XDP 程序明確流程選擇eBPF庫編寫eBPF代碼編寫Go代碼動態更新黑名單 預備知識 TCP/IP…

[每周一更]-(第137期):Go + Gin 實戰:Docker Compose + Apache 反向代理全流程

文章目錄 **1. Go 代碼示例&#xff08;main.go&#xff09;****2. Dockerfile 多段構建**3.構建 Docker 鏡像**4. docker-compose.yml 直接拉取鏡像****5. 運行容器****6. 測試 API**7、配置域名訪問**DNS解析&#xff1a;將域名轉換為IP地址****DNS尋址示例** 8.錯誤記錄 訪問…

SpringMVC基本使用

SpringMVC是什么&#xff1f; Spring MVC 是 Spring 框架中的一個模塊&#xff0c;用于構建基于 MVC&#xff08;Model-View-Controller&#xff09;設計模式的 Web 應用程序。它分離了應用程序的業務邏輯、用戶界面和用戶輸入&#xff0c;使開發更加模塊化和易于維護。 核心…

Qt之MVC架構MVD

什么是MVC架構&#xff1a; MVC模式&#xff08;Model–view–controller&#xff09;是軟件工程中的一種軟件架構模式&#xff0c;把軟件系統分為三個基本部分&#xff1a;模型&#xff08;Model&#xff09;、視圖&#xff08;View&#xff09;和控制器&#xff08;Controll…

Stream 流中 flatMap 方法詳解

&#x1f3af; 1. flatMap() 到底是啥&#xff1f; flatMap() 是 Stream 里的中間操作&#xff0c;它的作用可以分兩步理解&#xff1a; 第一步&#xff1a;對流里的每個元素&#xff0c;先**映射&#xff08;轉換&#xff09;**成一個 Stream。第二步&#xff1a;把多個子流…

(C語言)理解 回調函數 和 qsort函數

一. 回調函數 1. 什么是回調函數&#xff1f; 回調函數&#xff08;Callback Function&#xff09;是通過 函數指針 調用的函數。其本質是&#xff1a; 將函數作為參數傳遞給另一個函數&#xff0c;并在特定條件下被調用&#xff0c;實現 反向控制。 2. 回調函數的使用 回調函…

vscode記錄

vs code 下載安裝&#xff0c;git 配置&#xff0c;插件安裝_vscode安裝git插件-CSDN博客 手把手教你在VS Code中使用 Git_vscode如何輸入git命令-CSDN博客 VS Code | 如何快速重啟VS Code&#xff1f;_vscode 怎么一鍵全部重啟-CSDN博客 1&#xff0c;安裝插件與git集成 2&am…