java锁Synchronized和ReentrantLock

news2024/11/25 10:35:36

        上周,我为“心情追忆”小程序添加了支付功能,用户可以通过支付0.1元来增加一次心情分析的机会。支付功能是一个非常重要的功能,我担忧可能出现的并发问题,例如当多个用户几乎同时进行支付操作时,可能会导致系统只记录了一次支付的情况。为了确保每个支付请求都能正确地增加分析次数,适当使用锁机制成为了必要的解决方案。

以下是两种基本的锁类型及其工作原理:

  1. 互斥锁(Mutex):当一个线程获取到锁后,其他试图获取同一锁的线程将直接返回失败。这种锁保证了在任意时刻只有一个线程能够访问被锁定的资源,从而避免了数据的不一致问题。互斥锁适用于那些不需要等待锁释放就能立即做出响应的场景。

  2. 信号量(Semaphore)或可重入锁(Reentrant Lock):当一个线程获取到了锁,其他线程会进入等待状态,直到第一个线程释放锁。之后,等待队列中的下一个线程将获得锁。这种方式可以保证所有等待的线程最终都能得到执行的机会,适用于需要长时间持有锁或有顺序执行要求的场景。

Synchronized关键字的底层原理

synchronized是一个内置的同步机制,它可以用来控制多线程对共享资源的访问。synchronized关键字通过在对象头中设置锁标志位来实现锁机制。当一个线程尝试进入由synchronized修饰的方法或代码块时,它必须先获取该方法或代码块所属对象的锁。如果锁已经被其他线程持有,则当前线程将被阻塞,直到锁被释放。

Synchronized的底层实现依赖于Java对象头中的Mark Word,其中包含了对象的哈希码、对象的分代年龄、锁标志位等信息。当线程尝试获取锁时,会检查Mark Word中的锁标志位来判断是否已经上锁以及锁的状态。

ReentrantLock
  • ReentrantLock:可重入锁是一种更灵活的锁机制,它允许同一个线程多次获取同一把锁而不会发生死锁。与synchronized不同的是,ReentrantLock提供了更多的功能,比如尝试非阻塞地获取锁(tryLock)、可中断地获取锁(lockInterruptibly)等。此外,ReentrantLock还支持公平锁和非公平锁的选择,前者按照请求锁的顺序分配锁,后者则允许插队,提高吞吐量。

特性synchronizedReentrantLock
锁类型内置锁显式锁
可重入性可重入可重入
公平性非公平(默认)可选公平或非公平
锁的释放自动释放(方法结束或异常抛出时)手动释放(需要调用 unlock() 方法)
等待可中断不可中断可中断(lockInterruptibly() 方法)
尝试非阻塞获取锁不支持支持(tryLock() 方法)
锁的绑定绑定到对象绑定到 ReentrantLock 实例
性能早期版本性能较差,JDK 1.6+ 优化后性能接近 ReentrantLock通常性能较好,特别是在高竞争环境下
使用复杂度简单,自动管理锁较复杂,需要手动管理锁的获取和释放
适用场景简单的同步需求,代码块或方法级同步复杂的同步需求,需要更多灵活性和高级特性

下面是简单的测试代码

private int a = 0;

    private synchronized void add(String name) {
        System.out.println(name+"开始");
        a++;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+":"+a);
    }

    @Test
    public void test() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        executorService.submit(() -> {
            System.out.println("a");
            add("a");
        });

        executorService.submit(() -> {
            System.out.println("b");
            add("b");
        });

        executorService.submit(() -> {
            System.out.println("c");
            add("c");
        });

        executorService.submit(() -> {
            System.out.println("d");
            add("d");
        });

        // 关闭线程池,不再接受新的任务
        executorService.shutdown();
        // 等待所有已提交的任务完成,最长等待时间为1分钟
        if (!executorService.awaitTermination(1, TimeUnit.MINUTES)) {
            executorService.shutdownNow(); // 如果超时则强制关闭线程池
        }
    }


// 输出
a
a开始
b
c
d
a:1
d开始
d:2
c开始
c:3
b开始
b:4
总结

        对于“心情追忆”小程序而言,考虑到支付操作的敏感性,采用ReentrantLock可能是更为合适的选择。这不仅因为其提供了比synchronized更强大的功能,还因为它可以更好地控制锁的获取方式,确保支付操作的原子性和一致性。在实际应用中,应当根据具体的业务需求选择最合适的锁策略,以达到最佳的并发控制效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物体网格弹性变形---Unity中实现

在游戏引擎场景中的3D物体是由一定数量的点、面组成的,如下图: 要使这些物体变形就是改变3D物体每个顶点状态。 1.首先在Unity场景中增加一个球体,如下图 3D组件默认拥有MeshFilter、meshRenderer、Collider组件,分别用来获取Mes…

【ArcGISPro】根据yaml构建原始Pro的conda环境

使用场景 我们不小心把原始arcgispro-py3的conda环境破坏了,我们就可以使用以下方法进行修复 查找文件 在arcgis目录下找到yaml文件 如果没找到请复制以下内容到新的yaml文件 channels: - esri - defaults dependencies: - anyio=4.2.0=py311haa95532_0 - appdirs=1.4.4=p…

【Y20030007】基于java+servlet+mysql的垃圾分类网站的设计与实现(附源码 配置 文档)

网垃圾分类网站的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 随着全球环境保护意识的提升,垃圾分类已成为一项紧迫且重要的任务。为了有效推动垃圾分类的实施,提升公众的环保意识和参与度,垃圾分类已…

【Python爬虫五十个小案例】爬取豆瓣电影Top250

博客主页:小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介:分享五十个Python爬虫小案例 🪲前言 在这篇博客中,我们将学习如何使用Python爬取豆瓣电影Top250的数据。我们将使用requests库来发送HTTP请求,…

C++ 优先算法 —— 长度最小的子数组(滑动窗口)

目录 题目:长度最小的子数组 1. 题目解析 2. 算法原理 Ⅰ. 暴力枚举 Ⅱ. 滑动窗口(同向双指针) 滑动窗口正确性 3. 代码实现 Ⅰ. 暴力枚举(会超时) Ⅱ. 滑动窗口(同向双指针) 题目:长…

C++设计模式——Singleton单例模式

一、单例模式的定义 单例模式,英文全称Singleton Pattern,是一种创建型设计模式,它保证一个类在程序中仅有一个实例,并对外提供一个访问的该类实例的全局接口。 单例模式通常用于需要控制对象资源的开发场景,一个类…

【Linux系统】—— 基本指令(三)

【Linux系统】—— 基本指令(三) 1 一切皆文件2 重定向操作2.1 初始重定向2.2 重定向的妙用2.3 追加重定向2.4 输入重定向2.5 一切皆文件与重定向结合 3 Linux 中的文件类型4 日志5 「more」命令6 「less」命令7 「head」与「tail」7.1 查看文件开头和结…

探索 Python 任务自动化的新境界:Invoke 库揭秘

文章目录 探索 Python 任务自动化的新境界:Invoke 库揭秘背景:为何选择 Invoke?什么是 Invoke?如何安装 Invoke?5个简单的库函数使用方法1. 定义任务2. 带参数的任务3. 运行 Shell 命令4. 任务参数化5. 列出任务 场景应…

【C++】list模拟实现(详解)

本篇来详细说一下list的模拟实现,list的大体框架实现会比较简单,难的是list的iterator的实现。我们模拟实现的是带哨兵位头结点的list。 1.准备工作 为了不和C库里面的list冲突,我们在实现的时候用命名空间隔开。 //list.h #pragma once #…

shell脚本(6)

声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:shell(6)if条件判断与for循环结构_哔哩哔哩_bilibili 本文主要讲解shell脚本中的if条件判断和for循环结构。 一、if语句 Shell 脚本中的 if 语句…

JavaScript基础 document.write()方法

JavaScript基础 document.write方法 1.简单认识document.write()2.document.write() 的使用 1.简单认识document.write() document.write() 是一种 JavaScript 方法,用于将内容直接写入到 HTML 文档中。它可以用来动态地在页面加载时插入文本、HTML 代码、图片等内…

Linux笔记---进程:进程切换与O(1)调度算法

1. 补充概念 1.1 并行与并发 竞争性:系统进程数目众多,而CPU资源只有少量,甚至只有1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。独立性:多进程运…

使用ENSP实现浮动静态路由

一、项目拓扑 二、项目实现 1.路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1关闭信息中心 undo info-center enable 进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为1.1.1.1/24 ip address 1.1.1.1 24进入g0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置为2.…

GoF设计模式——结构型设计模式分析与应用

文章目录 UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。1. 继承(抽象,泛化关系)2. 关联3. 组合/聚合各种可能的配合:1. 关联后抽象2. 关联的集合3. 组合接口4. 递归聚合接…

【论文复现】深度知识追踪

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 深度知识追踪 1. 论文概述2. 论文方法3. 实验部分3.1 数据集3.2 实验步骤3.3 实验结果 4 关键代码 1. 论文概述 知识追踪的任务是对学生的知…

Linux: 进程地址空间(理解虚拟地址和页表)

目录 1. 虚拟地址 2. 进程地址空间分布 3. 描述进程地址空间 4. 内存管理——页表 5. 父子进程的虚拟地址关系 6. 页表标记位 6.1 读写权限 6.2 命中权限 7.为什么存在进程地址空间 1. 虚拟地址 #include <stdio.h> #include <unistd.h> #include <sy…

C语言:深入理解指针

一.内存和地址 我们知道计算机上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数据也会放回内存中&#xff0c;那我们买电脑的时候&#xff0c;电脑上内存是 8GB/16GB/32GB 等&#xff0c;那这些内存空间…

transformer.js(一):这个前端大模型运行框架的可运行环境、使用方式、代码示例以及适合与不适合的场景

随着大模型的广泛应用&#xff0c;越来越多的开发者希望在前端直接运行机器学习模型&#xff0c;从而减少对后端的依赖&#xff0c;并提升用户体验。Transformer.js 是一个专为前端环境设计的框架&#xff0c;它支持运行基于 Transformer 架构的深度学习模型&#xff0c;尤其是…

uni-app 发布媒介功能(自由选择媒介类型的内容) 设计

1.首先明确需求 我想做一个可以选择媒介的内容&#xff0c;来进行发布媒介的功能 &#xff08;媒介包含&#xff1a;图片、文本、视频&#xff09; 2.原型设计 发布-编辑界面 通过点击下方的加号&#xff0c;可以自由选择添加的媒介类型 但是因为预览中无法看到视频的效果&…

行业分析---2024年小鹏汽车AI Day及三季度财报

1 背景 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 《行业分析-…