Java的锁机制详解
在并发编程中,锁 是用于控制多个线程对共享资源进行访问的工具。Java提供了多种锁机制,从最基础的 synchronized 到高级的 ReentrantLock,这些锁帮助我们确保线程安全,并能有效避免数据竞争和死锁问题。

1. synchronized 关键字
synchronized 是Java中最简单的锁机制。它可以锁住方法或者代码块,确保某个线程在访问共享资源时,其他线程无法访问同一个资源。
示例代码:同步方法
public class SynchronizedExample {public synchronized void synchronizedMethod() {System.out.println("Thread " + Thread.currentThread().getName() + " is executing synchronized method.");}
}
在上述代码中,synchronizedMethod 方法被 synchronized 关键字修饰,意味着同一时间只能有一个线程执行该方法。
示例代码:同步代码块
public class SynchronizedBlockExample {private final Object lock = new Object();public void synchronizedBlock() {synchronized (lock) {System.out.println("Thread " + Thread.currentThread().getName() + " is executing synchronized block.");}}
}
使用同步代码块可以灵活地锁定某个对象(如上例中的 lock),只锁住需要保护的部分,而不是整个方法。
锁的粒度问题
synchronized 锁的粒度较粗,可能会导致性能瓶颈。对于更复杂的并发场景,ReentrantLock 等更灵活的锁机制是更好的选择。
2. ReentrantLock
ReentrantLock 是 Java java.util.concurrent.locks 包中的高级锁,它提供了更丰富的功能,如:公平锁、可重入性、可中断锁 等。
2.1 基本使用
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();public void execute() {lock.lock(); // 获取锁try {System.out.println("Thread " + Thread.currentThread().getName() + " is executing.");} finally {lock.unlock(); // 释放锁}}
}
在这个例子中,我们显式地调用 lock.lock() 来获取锁,并在 finally 中确保锁会被释放,以防止因异常导致死锁。
2.2 公平锁
默认情况下,ReentrantLock 是非公平锁,即等待时间长的线程不一定优先获得锁。你可以通过构造函数指定是否为公平锁:
ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
公平锁确保先请求锁的线程先获得锁,但相对性能较低。
3. ReadWriteLock
ReadWriteLock 是一种更细粒度的锁,它允许多个读线程同时访问共享资源,但在有写操作时,写线程会独占资源。典型的实现是 ReentrantReadWriteLock。
示例代码
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();public void read() {rwLock.readLock().lock();try {System.out.println("Thread " + Thread.currentThread().getName() + " is reading.");} finally {rwLock.readLock().unlock();}}public void write() {rwLock.writeLock().lock();try {System.out.println("Thread " + Thread.currentThread().getName() + " is writing.");} finally {rwLock.writeLock().unlock();}}
}
这种锁的优势在于读操作不互斥,当多个线程只读数据时,能够提高系统的吞吐量。但在写操作时,所有的读操作会被阻塞,确保数据的一致性。
4. 锁优化技术
4.1 偏向锁
偏向锁 是Java的轻量级锁优化策略。它假定大多数情况下锁不会被多个线程竞争,因此,第一次获取锁时,锁会偏向获取锁的线程。如果没有其他线程竞争,这个线程之后获取锁的代价几乎为零。
偏向锁适用于线程独占资源的场景,而不适用于高并发的竞争场景。
4.2 自旋锁
自旋锁 是通过让线程循环等待一段时间,而不立即进入阻塞状态,来减少上下文切换的开销。在高并发的环境中,如果线程持有锁的时间非常短,自旋锁可以提高性能。
Java在ReentrantLock的实现中结合了自旋锁的概念,当锁的竞争不激烈时,避免线程进入阻塞状态。
4.3 Lock Support
Java还提供了 LockSupport 类,用于线程的挂起和唤醒。这是实现高级并发工具(如CountDownLatch、CyclicBarrier等)的基础。
5. 总结
- synchronized:简单易用,适合基本的锁定需求,但灵活性较差。
- ReentrantLock:提供更丰富的功能,如可重入、锁超时、公平锁等,适用于复杂的并发场景。
- ReadWriteLock:读写分离,提高读多写少场景下的并发性能。
- 锁优化:如偏向锁、自旋锁、Lock Support等技术提高了锁的性能,适用于特定场景。
Java的锁机制虽然功能强大,但在实际开发中,我们需要根据具体场景选择合适的锁,并合理使用,以避免锁的滥用带来的性能问题。
相关文章:
Java的锁机制详解
在并发编程中,锁 是用于控制多个线程对共享资源进行访问的工具。Java提供了多种锁机制,从最基础的 synchronized 到高级的 ReentrantLock,这些锁帮助我们确保线程安全,并能有效避免数据竞争和死锁问题。 1. synchronized 关键字…...
用户登录与信息管理:实现小程序登录与用户信息存储
用户登录与信息管理:实现小程序登录与用户信息存储 在现代的移动应用中,用户登录与信息管理是构建个性化用户体验的基础。小程序作为轻量级的应用形式,在简化开发流程的同时,也需要我们妥善管理用户的登录状态与用户信息。本文将…...
Java如何调用构造函数和方法以及使用
调用构造函数的格式 构造函数在创建新对象时被调用。调用格式如下: ClassName objectName new ClassName(parameters); ClassName:你需要创建其实例的类的名称。 objectName:你将创建的对象的名称。 parameters:如果你使用的是…...
TFBoys谁最重
题目 使用go语言设计一个程序计算TFBoys谁最重,要求使用结构体表示TFBoys三个成员,设计函数计算三个重量的最大值。 程序 package main import ("fmt") type Person struct {Name stringWeight float64} func (p Person) GetWeigh…...
scp 通过中间机器进行远程拷贝
有时候,我们想要通过 scp将一台机器上的文件拷贝至另外一台机器,但这两台机器可能没有直接联通,需要通过中间机器进行跳转才能访问,一个麻烦的办法就是,先将文件拷贝至中间机器,然后再从中间机器拷贝至另外…...
探索 Python 高精度计算的奥秘:mpmath 库全解析
文章目录 探索 Python 高精度计算的奥秘:mpmath 库全解析背景:为何选择 mpmath?第二部分:mpmath 是什么?第三部分:如何安装 mpmath?第四部分:mpmath 函数使用示例第五部分࿱…...
<<迷雾>> 第10章 用机器做一连串的加法(1)--使用两排开关分别给出被加数和加数 示例电路
info::操作说明 鼠标单击逻辑输入切换 0|1 状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch10-01-5-bit-adder.txt 原图...
Stable Diffusion最新版nowebui的api使用详解
最近在使用stable diffusion最新版的Stable Diffusion WebUI Forge进行api调用,下面来一步一步的进行展开吧!!! 1、下载lllyasviel/stable-diffusion-webui-forge GitHub - lllyasviel/stable-diffusion-webui-forgeContribute to lllyasviel/stable-diffusion-webui-for…...
云服务器架构详解:X86计算_ARM_GPU/FPGA/ASIC_裸金属_超级计算集群
阿里云服务器架构有什么区别?X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、超级计算集群有什么区别?阿里云服务器网aliyunfuwuqi.com分享云服务器ECS架构详细说明: 阿里云服务器ECS架构说明 阿里云服务器ECS架构 X86计算 X86计算架…...
高级java每日一道面试题-2024年10月4日-数据库篇-MySQL索引底层结构为什么使用B+树?
如果有遗漏,评论区告诉我进行补充 面试官: MySQL索引底层结构为什么使用B树? 我回答: 该面试题本质还是在考察B树的数据结构和在数据库系统中的应用,下边是详细的回答。 B树的基本特性 B 树的结构特点 非叶子节点只存储键值信息,不存储…...
【JVM】内存分析工具JConsole/Visual VM
1 缘起 日常补充JVM调优,调优实践前需要学习一些理论做支撑, JVM调优三步:理论>GC分析>JVM调优, 我们会有一些玩笑话说,做了这么久Java开发,做过JVM调优吗? 做过,面试时。当然…...
一静 、二平 、三忍 、四让、五淡
一静 、二平 、三忍 、四让、五淡。 作者:儒风君 来源:儒风大家(ID: rufengdajia) 古人为人、处事、修身,都有独特的章法。 一静、二平、三忍、四让、五淡。 说透中国人的大智慧。 1 静 《道德经》里讲:“清静为天下正。”…...
js 深入理解函数(一):函数的本质
目录 概述1. 箭头函数2. 函数名 :指向函数的指针3. 理解参数3.1 arguments 对象的作用3.2 arguments 的注意点3.3 箭头函数中的参数 4. 没有重载5. 默认参数值5.1 ES 6 支持显示定义默认参数5.2 传 undefined 等于没有传值5.3 arguments 不反映参数默认值5.4 默认值…...
MySql表结构设计
创建 create table 表名(字段1 字段类型 [约束] [comment 字段1注释],...) [comment 表注释];约束是作用于表中字段上的规则,用于限制存储在表中的数据。它的目的是保证数据库中数据的正确性、有效性和完整性。 约束描述关键字非空约束限制该字段不能为nullnot nu…...
java:pdfbox 3.0 去除扫描版PDF中文本水印
官网下载 https://pdfbox.apache.org/download.html下载 pdfbox-app-3.0.3.jar cd D:\pdfbox 运行 java -jar pdfbox-app-3.0.3.jar java -jar pdfbox-app-3.0.3.jar Usage: pdfbox [COMMAND] [OPTIONS] Commands:debug Analyzes and inspects the internal structu…...
python知识点100篇系列(17)-替换requests的python库httpx
Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,使用Requests可以轻而易举的完成浏览器可有的任何操作。 但是在python3.6之后,出现了一个requests的替代选项; httpx httpx是Python新一代的网络请求库…...
python 实现graph list图列算法
graph list图列算法介绍 图列(Graph List)算法通常指的是在图的表示中,使用列表(List)或更具体地说,邻接表(Adjacency List)来表示图的一种算法。邻接表是图的一种常见表示方法&…...
LFU算法 初始频率 动态频率
LFU(Least Frequently Used)算法是一种缓存淘汰策略,其核心思想是根据数据的访问频率来决定淘汰哪些数据。具体来说, LFU算法认为如果一个数据在过去一段时间内被访问的次数很少,那么它在未来被再次访问的概率也…...
Spring Boot 进阶-详解SpringBoot的复杂数据校验规则
在之前的文章中,我们介绍了SpringBoot整合JSR-303规则来完成数据校验操作。接下来我们来聊一聊关于数据校验的具体用法。 之前的文章中举过一个简单的例子通过学生信息提交的例子来介绍了关于数据校验如何去做。那么接下来这篇文章,我们就来看看对于一些复杂的数据校验如何完…...
wsl环境下安装Ubuntu,并下载MySQL5.7
安装操作需root权限,切换root用户有两种方式: 1-通过 sudo su - ,切换到root用户(登录后长期有效)。 2-在每一个命令前加上sudo,临时提升权限(仅对一条命令有效)。 1、下载apt仓库…...
联发科MT6873核心板:5G安卓设备开发实战与硬件设计指南
1. 项目概述:MT6873核心板,一款为智能终端注入5G灵魂的“心脏”在智能硬件开发领域,选对一颗“心脏”——也就是核心板或主控模块,往往决定了整个产品的性能上限、功能边界和市场竞争力。今天要深入聊的,就是联发科&am…...
为什么所有人都在聊RAG?看这篇,小白也能彻底搞懂
你是否有过这样的经历——你满怀期待地问 AI 一个专业问题,它流畅地给了你一段"答案",引经据典、逻辑自洽。 结果一查,发现全是错的。一本正经地胡说八道。 这就是大语言模型(LLM)的致命短板:它…...
Nmap - Zenmap GUI工具
1、Nmap - Zenmap GUI工具1)设备和电脑在同一局域网内,输入设备ip,点击Scan(本地web接口安全)...
手把手教你定制专属标注工具:基于Python3+Tkinter打造你的实体关系标注器
从零构建领域专用标注工具:Python3Tkinter实战指南 在自然语言处理项目中,高质量标注数据是模型效果的基石。当面对法律条文、医疗报告等专业领域时,通用标注工具往往难以满足特定实体关系和输出格式需求。本文将带你深入开发一个完全可控的实…...
Vidupe:3步快速清理重复视频的终极免费解决方案
Vidupe:3步快速清理重复视频的终极免费解决方案 【免费下载链接】vidupe Vidupe is a program that can find duplicate and similar video files. V1.211 released on 2019-09-18, Windows exe here: 项目地址: https://gitcode.com/gh_mirrors/vi/vidupe 您…...
Kindle Comic Converter终极指南:解锁电子墨水屏漫画阅读体验
Kindle Comic Converter终极指南:解锁电子墨水屏漫画阅读体验 【免费下载链接】kcc KCC (a.k.a. Kindle Comic Converter) is a comic and manga converter for ebook readers. 项目地址: https://gitcode.com/gh_mirrors/kc/kcc 你是否曾尝试在Kindle或Kobo…...
CANN/asc-devkit SIMD向量长度获取函数
GetVecLen 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/…...
cstore_fdw迁移指南:从传统表到列式存储的无缝切换
cstore_fdw迁移指南:从传统表到列式存储的无缝切换 【免费下载链接】cstore_fdw Columnar storage extension for Postgres built as a foreign data wrapper. Check out https://github.com/citusdata/citus for a modernized columnar storage implementation bui…...
使用curl命令直接测试taotoken api的连通性与基础功能
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用curl命令直接测试taotoken api的连通性与基础功能 基础教程类,面向需要快速验证或在不便安装SDK的环境中进行操作的…...
AntiDupl.NET终极指南:免费开源图片去重工具快速清理硬盘重复图片
AntiDupl.NET终极指南:免费开源图片去重工具快速清理硬盘重复图片 【免费下载链接】AntiDupl A program to search similar and defect pictures on the disk 项目地址: https://gitcode.com/gh_mirrors/an/AntiDupl 你是否曾为电脑中堆积如山的重复图片而烦…...
