当前位置: 首页 > news >正文

什么时候用synchronized,什么时候用Reentrantlock

文章目录

  • 使用 synchronized 的场景
  • 使用 ReentrantLock 的场景
  • 综合考虑

使用 synchronized 的场景

synchronized 是 Java 内置的同步机制,使用起来比较简单且常用于如下场景:

1、简单的同步逻辑:当你的同步逻辑非常简单,比如只需要对某个方法或代码块进行互斥访问时,synchronized 非常适用,因为它的语法简洁且易于维护。

public synchronized void simpleMethod() {// critical section
}

2、隐式监视器锁:synchronized 隐式地使用对象的监视器锁来控制同步,不需要显式的锁定和解锁操作,因此避免了锁忘记释放的问题。

3、异常安全:synchronized 块在异常发生时,会自动释放锁,确保不会因为未释放锁而导致死锁问题。

使用 ReentrantLock 的场景

ReentrantLock 是 java.util.concurrent.locks 包中提供的,更高级的锁机制,适用于以下场景:

1、需要更灵活的锁控制:ReentrantLock 提供了更多的锁控制功能,如 tryLock()(尝试锁定)和 lockInterruptibly()(可中断锁定),使得能够响应中断或超时。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class TryLockExample {private final Lock lock = new ReentrantLock();public void tryMethod() {if (lock.tryLock()) {try {// critical section} finally {lock.unlock();}} else {// handle the case where lock was not acquired}}
}

2、需要公平锁机制:ReentrantLock 支持公平锁(即先请求先获得锁),这在某些需要防止线程饥饿的场景中特别有用。

Lock fairLock = new ReentrantLock(true); // true for fairness

3、需要条件变量:ReentrantLock 提供了条件变量(Condition),可以更精细地控制线程等待和通知机制,适用于需要多个条件队列的复杂同步场景。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;// 假设我们有一个界面程序,其中一个生产者线程和两个消费者线程,
// 并且我们希望消费者1只处理奇数编号的任务,而消费者2只处理偶数编号的任务。
public class MultiConditionExample {private static final Lock lock = new ReentrantLock();private static final Condition conditionOdd = lock.newCondition();private static final Condition conditionEven = lock.newCondition();private static int count = 0;public static void main(String[] args) {Thread producer = new Thread(new Producer());Thread consumer1 = new Thread(new ConsumerOdd(), "Consumer-Odd");Thread consumer2 = new Thread(new ConsumerEven(), "Consumer-Even");producer.start();consumer1.start();consumer2.start();}static class Producer implements Runnable {@Overridepublic void run() {while (true) {try {lock.lock();count++;System.out.println("Produced: " + count);if (count % 2 == 0) {conditionEven.signal();  // Signal consumers waiting on even condition} else {conditionOdd.signal();  // Signal consumers waiting on odd condition}} finally {lock.unlock();}try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}static class ConsumerOdd implements Runnable {@Overridepublic void run() {while (true) {try {lock.lock();while (count % 2 == 0) {conditionOdd.await();  // Wait for odd number condition}// Process odd numberSystem.out.println(Thread.currentThread().getName() + " consumed: " + count);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}}}static class ConsumerEven implements Runnable {@Overridepublic void run() {while (true) {try {lock.lock();while (count % 2 != 0) {conditionEven.await();  // Wait for even number condition}// Process even numberSystem.out.println(Thread.currentThread().getName() + " consumed: " + count);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}}}
}
class MultiConditionExampleWithWaitNotify {private static final Object lock = new Object();private static int count = 0;public static void main(String[] args) {Thread producer = new Thread(new Producer());Thread consumerOdd = new Thread(new ConsumerOdd(), "Consumer-Odd");Thread consumerEven = new Thread(new ConsumerEven(), "Consumer-Even");producer.start();consumerOdd.start();consumerEven.start();}static class Producer implements Runnable {@Overridepublic void run() {while (true) {synchronized (lock) {count++;System.out.println("Produced: " + count);if (count % 2 == 0) {lock.notifyAll(); // Notify consumers waiting on even condition} else {lock.notifyAll(); // Notify consumers waiting on odd condition}}try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}static class ConsumerOdd implements Runnable {@Overridepublic void run() {while (true) {synchronized (lock) {try {while (count % 2 == 0) {lock.wait(); // Wait for odd number condition}// Process odd numberSystem.out.println(Thread.currentThread().getName() + " consumed: " + count);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}}static class ConsumerEven implements Runnable {@Overridepublic void run() {while (true) {synchronized (lock) {try {while (count % 2 != 0) {lock.wait(); // Wait for even number condition}// Process even numberSystem.out.println(Thread.currentThread().getName() + " consumed: " + count);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}}}
}

wait 和 notify:只能使用单一的监视器锁,并通过 notify 或 notifyAll 来通知等待线程。由于所有线程都在同一个锁对象上等待,即使只需要唤醒部分线程(例如只唤醒等待奇数的线程),也必须通知所有等待的线程(使用 notifyAll),这样会导致非目标线程频繁被唤醒和再次等待

Condition:可以创建多个 Condition 实例,在不同的条件队列上管理等待和通知。只会唤醒指定条件下的线程,从而提高效率。

综合考虑

简洁性和安全性:如果你的同步需求简单,且不需要复杂的锁定逻辑,选择 synchronized 更为简洁和安全。

灵活性和功能:如果需要更灵活的锁控制、更高的性能、更多的特性(如条件变量、尝试锁定、响应中断等),ReentrantLock 提供更强大的功能。

相关文章:

什么时候用synchronized,什么时候用Reentrantlock

文章目录 使用 synchronized 的场景使用 ReentrantLock 的场景综合考虑 使用 synchronized 的场景 synchronized 是 Java 内置的同步机制,使用起来比较简单且常用于如下场景: 1、简单的同步逻辑:当你的同步逻辑非常简单,比如只需…...

[ffmpeg]音频格式转换

本文主要梳理 ffmpeg 中的音频格式转换。由于采集的音频数据和编码器支持的音频格式可能不一样,所以经常需要进行格式转换。 API 调用 常用 API struct SwrContext *swr_alloc(void); int swr_init(struct SwrContext *s); struct SwrContext *swr_alloc_set_opt…...

SSRF工具类-SsrfTool

为了帮助开发人员和安全研究人员检测和修复SSRF(Server-Side Request Forgery)漏洞,存在 多种工具。这里我将给出一个简单的工具类示例,这个工具类可以用来检查一个给定的URL是否可 能引发SSRF攻击。请注意,这个工具类主要用于教育目的,并不意味着它可以完全防止所有的…...

python集合运算介绍及示例代码

Python 中的集合(set)是一种数据类型,用于存储唯一元素的无序集合。集合支持多种运算,如并集、交集、差集和对称差集,方便执行数学上的集合操作。 1. 创建集合 可以使用大括号 {} 或者 set() 函数创建集合&#xff1…...

『功能项目』按钮的打开关闭功能【73】

本章项目成果展示 我们打开上一篇72QFrameWork制作背包界面UGUI的项目, 本章要做的事情是制作打开背包与修改器的打开关闭按钮 首先打开UGUICanvas复制button按钮 重命名为ReviseBtn 修改脚本:UIManager.cs 将修改器UI在UGUICanvas预制体中设置为隐藏 运…...

Linux 常用命令 - more 【分页显示文件内容】

简介 more 命令源自英文单词 more, 表示 “更多”,它是一个基于文本的程序,用于查看文本文件的内容。该命令会逐页显示文件内容,允许用户按页浏览大型文本文件。当用户完成当前页的阅读后,可以通过按键(空格键或回车键…...

Kotlin Android 环境搭建

Kotlin Android 环境搭建 1. 引言 Kotlin 已成为 Android 开发的官方语言之一,因其简洁、表达性强和易于维护的特点而受到广大开发者的喜爱。在本教程中,我们将详细介绍如何在您的计算机上搭建 Kotlin Android 开发环境。 2. 系统要求 在开始搭建 Kotlin Android 开发环境…...

常见协议及其默认使用的端口号

在网络通信中,端口号用于标识特定的应用程序或服务。IANA(Internet Assigned Numbers Authority)负责分配和管理这些端口号。端口号分为三个范围: 熟知端口(Well-Known Ports):0到1023&#xf…...

04-Docker常用命令

04-Docker常用命令 启动类命令 启动docker systemctl start docker停止docker systemctl stop docker重启docker systemctl restart docker查看docker状态 systemctl status docker开机启动docker systemctl enable docker帮助类命令 查看docker版本 docker version查…...

数字化转型中的供应链管理优化

在当今全球化和数字化的浪潮下,企业供应链管理面临着前所未有的挑战和机遇,企业在数字化转型过程中,如何优化供应链管理成为提升竞争力的关键。通过应用先进技术如RPA机器人流程自动化、大数据分析、物联网等,企业可以显著提高物流…...

【Python报错已解决】SyntaxError: invalid syntax

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…...

树上差分+lca 黑暗的锁链

//** 太久不写了,感觉很难受。。。比赛最近打得也不好,课内任务又重,还要忙着做项目。何去何从。 今天又写了一题,用了树上差分的知识。下面来整理整理。 1.首先让我们学一下lca(最小公共父节点) 我用的…...

opencv4.5.5 GPU版本编译

一、安装环境 1、opencv4.5.5 下载地址:https://github.com/opencv/opencv/archive/refs/tags/4.5.5.ziphttps://gitee.com/mirrors/opencv/tree/4.5.0 2、opencv-contrib4.5.5 下载地址:https://github.com/opencv/opencv_contrib/archive/refs/tags/4…...

线性跟踪微分器TD详细测试(Simulink 算法框图+SCL完整源代码)

1、ADRC线性跟踪微分器 ADRC线性跟踪微分器(ST+SCL语言)_adrc算法在博途编程中scl语言-CSDN博客文章浏览阅读784次。本文介绍了ADRC线性跟踪微分器的算法和源代码,包括在SMART PLC和H5U平台上的实现。文章提供了ST和SCL语言的详细代码,并讨论了跟踪微分器在自动控制中的作用…...

LabVIEW闪退

LabVIEW闪退或无法启动可能由多个原因引起,特别是在使用了一段时间后突然发生的问题。重启电脑后 LabVIEW 和所有 NI 软件都无法打开,甚至在卸载和重装时也没有反应。这种情况通常与系统环境、软件冲突或 NI 软件组件的损坏有关。 1. 检查系统和软件冲突…...

【WPF】03 动态生成控件

说明 今天记录一篇关于动态生成控件的方法,也是反复查了一些资料,逐步完善成自己需要的方法,感觉还是比较好用的。通过这个需求,在网上也找了一些资料,发现了一个开源图形UI组件HandyControl,觉得比较好&a…...

调试LTE模块碰到的4字节对齐问题

在调试LTE模块,有两个模块,碰到两种4字节对齐问题,其错误提示都是类似如下的内容: DWC_OTG: dwc_otg_hcd_urb_enqueue urb->transfer_buffer address not align to 4-byte 0xee419e8e 都是USB控制器处理的数据时需要4字节对齐…...

一篇讲完HTML核心内容

一、HTML 1、 HTML概念 网页,是网站中的一个页面,通常是网页是构成网站的基本元素,是承载各种网站应用的平台。通俗的说,网站就是由网页组成的。通常我们看到的网页都是以htm或html后缀结尾的文件,俗称 HTML文件。 2、…...

2024icpc(Ⅱ)网络赛补题 G

2024icpc(Ⅱ)网络赛补题 G 题目链接:The 2024 ICPC Asia EC Regionals Online Contest (II) G、Game 题意: 给定Alice和Bob的每一轮的概率 p 0 , p 1 p_0, p_1 p0​,p1​ 给定Alice和Bob的初始数字 x , y x,y x,y。 对于每一轮: 如果Al…...

AIGC时代!AI的“iPhone时刻”与投资机遇

AIGC时代!AI的“iPhone时刻”与投资机遇 前言AI的“iPhone时刻”与投资机遇 前言 AIGC,也就是人工智能生成内容,它就像是一股汹涌的浪潮,席卷了整个科技世界。它的出现,让我们看到了人工智能的无限潜力,也…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...