JAVA 同步锁

news/2024/10/30 9:25:31/

文章目录

  • synchronized
    • synchronized 作用当前对象
    • synchronized 作用订单号条件
    • synchronized 作用订单号字符串条件
  • ReentrantLock 加 ConcurrentHashMap

需求: 同一个订单才加同步锁,不同订单可并行

synchronized

synchronized是Java中的关键字,是一种同步锁,是原生语法层面的互斥,需要jvm实现。它修饰的对象有以下几种:
  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

synchronized 作用当前对象

在这里插入图片描述
测试效果:
一)线程1 与 线程2 ,结果 线程1结束了线程2才开始。
在这里插入图片描述

synchronized 作用订单号条件

在这里插入图片描述
测试效果:
一)线程1 与 线程2 ,结果 线程1线程2可以同时开始。
在这里插入图片描述
二)线程1 与 线程1 ,结果 线程1与另一个线程1同时开始
synchronized 的锁不是比较字符串,而是对象,所以每次请求进来的orderId不是同一个对象。
在这里插入图片描述

synchronized 作用订单号字符串条件

把 synchronized 锁的 orderId 放在常量池中,那每次请求进来的就是同一个对象。
在这里插入图片描述
测试效果:
一)线程1 与 线程1 ,结果 线程1线程1锁住了。
在这里插入图片描述
二)线程1 与 线程2,结果 线程1与线程2同时开始。
在这里插入图片描述

ReentrantLock 加 ConcurrentHashMap

ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成

------------------------------------------------controller
@RestControllerpublic class OrderController{@AutowiredSynchronizedByKey synchronizedByKey;@ResponseBody@RequestMapping("")pubilc Map<String,Object> process(@PathVariable("orderId")String orderId){SynchronizedByKey.exec(orderId,() ->{logger.debug("[{}] 开始",orderId);logger.debug("[{}] 结束",orderId);});}
}------------------------------------------------SynchronizedByKey 
public class SynchronizedByKey {Map<String,ReentrantLock>  mutexCache = new ConcurrentHashMap<>;public void exec(String key,Runnable statement){ReentrantLock mutex4Key = null;ReentrantLock mutexInCache;do{if(mutex4Key != null){mutex4Key.unlock();}mutex4Key  = mutexCache.computeIfAbsent(key, k -> new ReentrantLock());mutex4Key.lock();/* lock()后再根据key去mutexCache取一把锁(mutexInCache),极端情况:1.我刚刚拿到了这把锁(mutexInCache),又从map里取的时候它为空了,说明我刚刚拿到的那么锁被remove掉了;2.我刚刚拿到了这把锁(mutexInCache),被新进来的线程(都是001)又创建了一把新锁覆盖了,所以mutex4Key 和 mutexInCache 不等; */mutexInCache = mutexCache.get(key);} while(mutexInCache == null || mutex4Key != mutexInCache);try{statement.run();} finally{if(mutex4Key.getQueueLength() == 0){mutexCache.remove(key);}mutex4Key.unlock();}}
}

学习视频链接


http://www.ppmy.cn/news/21447.html

相关文章

蓝桥杯算法训练合集九 1.计算税额2.数字统计3.删除字符串中的“*”4.2的次幂表示5.排序

目录 1.计算税额 2.数字统计 3.删除字符串中的“*” 4.2的次幂表示 5.排序 1.计算税额 问题描述 税务局希望你帮他们编写征税程序&#xff0c;该程序的功能是&#xff1a;首先输入某公司的年销售额sale和税率rate&#xff0c;然后程序将计算出相应的税额tax&#xff0c;并…

React之Diff算法

Diff算法概览 在beginWork中会使用Diff算法&#xff0c;对于Diff算法的本质是用来对比Current Fiber与JSX对象&#xff0c;来生成workInProgress Fiber。 对于Diff算法中&#xff0c;将两棵树完全比对的算法的复杂度为O(n3)&#xff0c;其中n是树中元素的数量&#xff0c;对于…

九龙证券|沪指收获2010年以来最强1月 北向资金净买入额刷新历史纪录

昨日&#xff0c;A股小幅调整&#xff0c;2023年1月行情随之收官。全体来看&#xff0c;1月A股商场拾级而上&#xff0c;盘面出现普涨格局&#xff0c;价值与生长风格均有亮眼体现。三大股指中&#xff0c;上证指数1月上涨5.39%&#xff0c;创2010年以来最佳局面。深证成指、创…

在产业互联网时代,以生态和边界为代表的有限市场的瓜分业已完成

在这样一个过程中&#xff0c;阿里们更多地思考的是&#xff0c;如何与产业结合&#xff0c;而非独立于产业之外&#xff0c;仅仅只是做一个旁观者和第三方。无论是它们投身到物流、制造、能源化工等行业之中&#xff0c;还是它们对这些产业的传统玩家们深度赋能&#xff0c;几…

windows系统使用Freeglut+glew库编写opengl程序(Mingw)

Freeglut glut是opengl实用工具集,由Mark Kilgrad所写。可以用来显示窗体,管理用户输入,字体,图像等操作,现在已经停止维护了,它的3.7版本是苹果电脑操作系统Mac OS 10.8(又名“美洲狮”)的opengl实用工具库的框架基础 使用更新的Freeglut替代glut,Freeglut是由Pawel…

【Mysql第五期 排序与分页】

文章目录案例使用的数据脚本1. 排序数据1.1 排序规则1.2 单列排序1.3 多列排序2.分页2.1 需求2.2 实现规则3.课后习题扩展分析原因问题解决总结案例使用的数据脚本 1.mysql脚本下载链接https://download.csdn.net/download/qq_43674360/87408079 2.或者自己新建一个sql后缀文本…

若依配置教程(七)Excel预览功能实现

实现效果及源码 实现效果如下图所示&#xff1a; 实现思路&#xff1a; 1.动态表格&#xff1a;定义表头数组&#xff0c;表格遍历表头生成表格列 2.读取excel文件内容&#xff0c;封装表头&#xff0c;绑定表格数据 代码修改 首先参考若依官网&#xff0c;先实现excel导入功…

webpack前端应用之基础打包

目录 前言&#xff1a;初识 Webpack 5 一、前端工程化 1、webpack ​ &#xff08;2&#xff09;主要功能&#xff1a; 2、webpack的使用&#xff1a;配置文件所需要的信息&#xff08;五大配置属性&#xff09; 3、示例 强调&#xff1a; 4、webpack中使用的loader 二…