JVM本地锁(一)简单实现

news2024/11/18 16:42:24

JVM本地锁由ReentrantLock或synchronized实现

模拟场景

假设有个共享库存资源,多线程进行访问,每次访问库存-1.

@Data
public class StockDemo {
    private Integer stock = 5000;
}

再controller -> service 进行访问调度

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();
    
    public void deduct(){
        stockDemo.setStock(stockDemo.getStock()-1);
        System.out.println("库存余量:" + stockDemo.getStock());
    }
}

注意:此时的stockDemo是单例模式,所有请求进来访问的是一个stockDemo实例。

@RestController
public class StockDemoController {

    @Autowired
    private StockDemoService stockDemoService;

    @GetMapping("/local/stock/deduct")
    public String deduct(){
        stockDemoService.deduct();
        return "hello stock deduct";
    }
}

端口号设置为10010.

启动完成后,通过页面访问
在这里插入图片描述

访问成功。

Jmeter并发测试

在这里插入图片描述
新建线程组,100个线程,每个线程发50个请求,请求间隔时间1s.

在这里插入图片描述
新建Http request,配置好发送路径
在这里插入图片描述
再配置好报表。

开始测试。
在这里插入图片描述

5000个请求执行完毕,吞吐量1520,没有错误。
那么如果正常来说,库存量此时应该是0。

在这里插入图片描述
查看控制台,发现最后库存并不是0,是604。
于是发生了超卖问题。即明明5000个商品已经卖完了,可是你显示还有库存,别的用户就还可以买。

synchronized

可以用synchronized解决,只要在service方法中加一个synchronized

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();

    public synchronized void deduct(){
        stockDemo.setStock(stockDemo.getStock()-1);
        System.out.println("库存余量:" + stockDemo.getStock());
    }
}

重启后成功,再用jmeter测试。
在这里插入图片描述
吞吐量明显升高了,1653。

synchronized的底层实现主要依靠 Lock-Free 的队列,基本思路是 自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量

再看控制台
在这里插入图片描述
库存清空,问题解决。

ReentrantLock

用ReentrantLock实现,修改下service方法

@Service
public class StockDemoService {
    private StockDemo stockDemo = new StockDemo();

    private ReentrantLock lock = new ReentrantLock();

    public void deduct(){
        lock.lock();
        try{
            stockDemo.setStock(stockDemo.getStock()-1);
            System.out.println("库存余量:" + stockDemo.getStock());
        }finally {
            lock.unlock();
        }
    }
}

注意:用的是try finally,为了保证最后肯定会调用lock.unlock()。

重启后再进行Jmeter测试

在这里插入图片描述
吞吐量明显降低,1035。

在这里插入图片描述
问题同样解决。

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

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

相关文章

题:付账问题

1235. 付账问题 - AcWing题库 几个人一起出去吃饭是常有的事。 但在结帐的时候,常常会出现一些争执。 现在有 nn 个人出去吃饭,他们总共消费了 SS 元。 其中第 ii 个人带了 aiai 元。 幸运的是,所有人带的钱的总数是足够付账的&#xff…

ctf笔记:php

ctf笔记:php 博客链接:https://www.blog.23day.site/articles/80 语法 攻防世界:easy_php 攻防世界:simple_php $a $b等于TRUE,如果类型转换后 $a 等于 $b。$a $b全等TRUE,如果 $a 等于 $b&#xff0c…

【封神台】辛巴猫舍-SQL注入

本节学习目标: 判断是否存在SQL漏洞,以便注入获取数据库的内容本节需知: SQL注入%20为空格的url代码环境为打靶环境1. 判断是否存在SQL漏洞 http://cntj8003.ia.aqlab.cn/index.php?id1%20and%2011 http://cntj8003.ia.aqlab.cn/index.php…

注册VMware虚拟机时报错“指定的项、名称或标识符已存在“

环境 VMware虚拟化平台 问题描述 收到业务侧报障,多台Linux虚拟机无法登录。经查询,报障的Linux操作系统均部署在VMware虚拟化平台,承载的宿主机已宕机且无法启动,虚拟机为断连状态。虚拟机移除清单,离线迁移&#…

图片识别转公式,GitHub 又一 LaTeX 神器面世

​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) 只需要把公式图片用鼠标拖动到工具内,就能一键转成 LaTex 公式。 写论文、做研究时,最让你头疼的是什么?想必公式编辑会榜上有名。那么有没有便捷的…

<Linux进程通信之管道>——《Linux》

目录 一、进程通信 1.进程间通信介绍 2.进程间通信目的 3.进程间通信发展 4.进程间通信分类 二、管道 1.什么是管道 2.匿名管道 3.用fork来共享管道原理 4.站在文件描述符角度-深度理解管道​编辑 5.编程模拟实现父子进程在管道读写通信​编辑 6.进程控制&#xff…

【DevOps实战系列】第一章:详解DevOps运行环境

个人亲自录制全套DevOps系列实战教程 :手把手教你玩转DevOps全栈技术 DevOps是什么? DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops&#x…

子序列的权值最小值

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 给定一个长度为 nnn 的数组 aaa,求数组所有非空子序列权值的最小值。 定义子序列 ai,aj,…,aka_i,a_{j},\dots,a_kai​,aj​,…,ak​ 的权值为 其中 &\&& 为二进制中…

Nat. Commun. | 基于最优传输的单细胞数据集成统一计算框架

本文介绍由同济大学控制科学与工程系的洪奕光和中国科学院数学与系统科学研究院的万林共同通讯发表在 Nature Communications 的研究成果:单细胞数据集成可以提供细胞的全面分子视图。然而,如何整合异质性单细胞多组学以及空间分辨的转录组学数据仍然是一…

Linux C编程一站式学习笔记3

lLinux C编程一站式学习笔记 chap3 简单函数 文章目录lLinux C编程一站式学习笔记 chap3 简单函数一.数学函数C标准库和glibc二.自定义函数三.形参和实参Man Page习题四.全局变量、局部变量和作用域局部变量 local variable全局变量 global variable全局变量和局部变量重名的情…

【linux】linux centos 6 日志服务、rsyslogd日志服务

1.概述 在CentOS 6.x中日志服务已经由rsyslogd取代了原先的syslogd服务。rsyslogd日志服 务更加先进,功能更多。但是不论该服务的使用,还是日志文件的格式其实都是和 syslogd服务相兼容的,所以学习起来基本和syslogd服务一致。 rsyslogd的新特点: 基于TCP网络协议传输日志…

测试人,为什么建议你要去大厂看一下,绝不仅仅是为了薪资和面子

📌 博客主页: 程序员二黑 📌 专注于软件测试领域相关技术实践和思考,持续分享自动化软件测试开发干货知识! 📌 公号同名,欢迎加入我的测试交流群,我们一起交流学习! 之前…

python数据容器分类

目录 一.数据容器可以从以下视角进行简单的分类: 1.是否支持下标索引 2.是否支持重复元素: 3.是否可以修改 二.数据容器特点对比 三.数据容器的通用操作 1.遍历 2.len(容器)、max(容器)、min(容器) 3.类型转换 注意 4.排序 一.数据容器可以从以下视角进行简单的分类:…

Clipper库 | 坐标圆整和精度控制

坐标圆整造成的问题 在Clipper库中顶点(IntPoint)的坐标使用的是整数类型, 目的是为了保持数字的鲁棒性,所以用整数类型来存储坐标,而不是我们常见的浮点数类型(浮点存在不精确性)。然而坐标圆…

Kerberos身份验证在ChunJun中的落地实践

Kerberos,在古希腊神话故事中,指的是一只三头犬守护在地狱之门外,禁止任何人类闯入地狱之中。 那么在现实中,Kerberos指的是什么呢? 一、Kerberos介绍 01 Kerberos是什么 根据百度词条释义,Kerberos是一…

Java——并查集

概念 当我们将多个元素分配到不同的集合中,这些集合有的是相关的,有的是不相关的。并查集就是用来查找两个元素是否在同一个集合中的 其主要实现方式是:将所有的元素以下标的形式存储在数组中。例如一共有十个人,那么就将这些人…

C语言tips-野指针

0.写在最前 最近因为工作需要开始重新学c语言,越学越发现c语言深不可测,当初用python轻轻松松处理的一些数据,但是c语言写起来却异常的复杂,这个板块就记录一下我的c语言复习之路 1. 什么是野指针? 如果一个指针指向的…

一文带你深入理解【Java基础】· IO流(上)

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

机器学习100天(五):005 数据预处理之划分训练集

机器学习100天,今天讲的是:数据预处理之划分训练集。 在上一节,我们对类别特征进行了编码,X 和 y 已经变成了机器学习可以理解和处理的数据格式。 下面我们就要对数据集进行划分,划分成训练集和测试集。 在监督式机器学习中,我们一般使用训练集的数据来训练模型,然后…

【LVGL学习笔记】(二) 基础概念

LVGL全程LittleVGL,是一个轻量化的,开源的,用于嵌入式GUI设计的图形库。并且配合LVGL模拟器,可以在电脑对界面进行编辑显示,测试通过后再移植进嵌入式设备中,实现高效的项目开发。 LVGL中文教程手册&#…