JVM中的java同步互斥工具应用演示及设计分析
1.火车站售票系统仿真
某火车站目前正在出售火车票,共有50张票,而它有3个售票窗口同时售票,下面设计了一个程序模拟该火车站售票,通过实现Runnable接口实现(模拟网络延迟)。
伪代码:
Ticket类:
Ticket = 50;//总共有张票
Run(){
While(true){
If ticket>0;//判断是否有余票
输出“正在出售第ticket- -张票”;
Else break;
Sleep(1000ms);//模拟网络延迟
}
}
MyTicket类:
Main(){
New Thread1 窗口1;//创建线程1
New Thread2 窗口2;//创建线程2
New Thread3 窗口3;//创建线程3
Start Thread1,Thread2,Thread3;//开启三个线程
}
运行结果(仅截取一部分):


上面的结果出现了相同票数的窗口,原因是ticket–不具有原子性,当窗口1休眠时,窗口3进入之后也休眠,这时窗口1苏醒了,进行到输出i的值这一步时,窗口3苏醒了并抢到了执行权,它也进行了输出i,由于上一步还没进行到i-1的步骤,因此窗口3和窗口1输出的值相同。因此需要限制修改票数的多并发。
下面一部分将介绍JVM中处理多线程并发时所用到的synchronized关键字,并介绍其是如何实现线程锁。
2.Java中synchronized关键字
2.1 synchronized关键字控制进程锁的实现结果
根据上一部分在售票过程中发现相同票数的窗口,为保证票数一致,针对多线程将才用synchronized关键字,对程序修改票数时上线程锁,在程序完成修改票数后释放线程锁。
伪代码:
Ticket类:
Ticket = 50;
Run(){
While(true){
Synchronized{//线程锁
If ticket>0;
输出“正在出售第ticket- -张票”;
Else break;
}
Sleep(1000ms);
}
}
MyTicket类:
Main(){
New Thread1 窗口1;
New Thread2 窗口2;
New Thread3 窗口3;
Start Thread1,Thread2,Thread3;
}
运行结果(仅截取一部分):


根据结果发现使用synchronized关键字后,售票数据正常,程序运行结果无误。
2.2 synchronized关键字
2.2.1 synchronized关键字的用法
① 当synchronized作用在实例方法时,监视器锁(monitor)便是对象实例(this);
② 当synchronized作用在静态方法时,监视器锁(monitor)便是对象的Class实例,因为Class数据存在于永久代,因此静态方法锁相当于该类的一个全局锁;
③ 当synchronized作用在某一个对象实例时,监视器锁(monitor)便是括号括起来的对象实例;
2.2.2 synchronized的同步原理
查看上述代码反汇编后的结果:
实现原理:
1.monitorenter:每个对象都是一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
① 如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者;
② 如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1;
③ 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权;
2.monitorexit:执行monitorexit的线程必须是objectref所对应的monitor的所有者。指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,不再是这个monitor的所有者。其他被这个monitor阻塞的线程可以尝试去获取这个 monitor 的所有权。(monitorexit指令出现了两次,第1次为同步正常退出释放锁;第2次为发生异步退出释放锁;)
3.监视器(Monitor)
任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。Synchronized在JVM里的实现都是基于进入和退出Monitor对象来实现方法同步和代码块同步,都可以通过成对的MonitorEnter和MonitorExit指令来实现。
1.MonitorEnter指令:插入在同步代码块的开始位置,当代码执行到该指令时,将会尝试获取该对象Monitor的所有权,即尝试获得该对象的锁;
2.MonitorExit指令:插入在方法结束处和异常处,JVM保证每个MonitorEnter必须有对应的MonitorExit;
####3.1 Monitor实现原理
Monitor可以把它理解为一个同步工具,也可以描述为一种同步机制,它通常被描述为一个对象。与一切皆对象一样,所有的Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中 ,每一个Java对象被创建初就带了一把看不见的锁,它叫做内部锁或者Monitor锁。也就是通常说Synchronized的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor实现的,其主要数据结构如下(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的):
ObjectMonitor() {_header = NULL;_count = 0; // 记录个数_waiters = 0,_recursions = 0;_object = NULL;_owner = NULL;_WaitSet = NULL; // 处于wait状态的线程,会被加入到_WaitSet_WaitSetLock = 0 ;_Responsible = NULL ;_succ = NULL ;_cxq = NULL ;FreeNext = NULL ;_EntryList = NULL ; // 处于等待锁block状态的线程,会被加入到该列表_SpinFreq = 0 ;_SpinClock = 0 ;OwnerIsThread = 0 ;}
ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象 ),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时:
1.首先会进入 _EntryList 集合,当线程获取到对象的monitor后,进入 _Owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;
2.若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSet集合中等待被唤醒;
3.若当前线程执行完毕,也将释放monitor(锁)并复位count的值,以便其他线程进入获取monitor(锁);
4.Java模拟PV原语
4.1信号量
count,如果是正值则表示当前资源的个数,如果是0,表示有一个进程在执行临界区的代码(也就是说这个进程位于临界区);并且没有进程处于阻塞队列中。如果是负值,这个值的绝对值(abs(count))表示阻塞队列中进程的个数。
queue,即为阻塞进程队列。当进程不能申请相应的资源是,则使用P操作,将自己插入阻塞队列中。当运行的进程执行完临界区代码时,就执行V操作,唤醒一个阻塞队列中的进程。
4.2功能实现
定义一个PV操作类:syn。在这个类中通过构造函数设置count的值。这个类中并没有阻塞进程所在的queue,是通过java的this.wait()与this.notifyAll()来实现的。
public class syn { //PV操作类int count=0;//信号量syn(){}syn(int a){count=a;}public synchronized void Wait(){ //关键字 synchronized 保证了此操作是一条【原语】count--;if(count<0){//等于0 :有一个进程进入了临界区try { //小于0:abs(count)=阻塞的进程数目this.wait();} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void Signal(){ //关键字 synchronized 保证了此操作是一条【原语】count++;if(count<=0){//如果有进程阻塞this.notify();}}
}
由此可以简单实现jvm中synchronized关键字的基本操作
相关文章:
JVM中的java同步互斥工具应用演示及设计分析
1.火车站售票系统仿真 某火车站目前正在出售火车票,共有50张票,而它有3个售票窗口同时售票,下面设计了一个程序模拟该火车站售票,通过实现Runnable接口实现(模拟网络延迟)。 伪代码: Ticket类…...
数据治理-数据质量
实现数据质量的前提就是数据本身是可靠和可信的。 导致数据质量低下的因素 组织缺乏对低质量数据影响的理解,缺乏规划、孤岛式系统设计、不一致的开发过程、不完整的文档、缺乏标准或缺乏治理等。 所有组织都会遇到与数据质量有关的问题。数据质量需要跨职能的承诺…...
[sqoop]hive3.1.2 hadoop3.1.1安装sqoop1.4.7
参考: Hadoop3.2.4Hive3.1.2sqoop1.4.7安装部署_hadoop sqoop安装_alicely07的博客-CSDN博客 一、安装 1、解压 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /home/data_warehouse/module mv sqoop-1.4.7.bin__hadoop-2.6.0 sqoop-1.4.72、配置文件 sqoop-env.s…...
js事件的详细介绍
11.事件 1.什么是事件 js属于事件驱动编程,把驱动,执行,调用通过一些交互,触发一些函数事件:发起-->执行绑定事件-->触发事件on 绑定 emit触发 off解绑2.事件分类 鼠标事件 点击事件 onclick 双击事件 ondblclick 按下事件 onmousedown 抬起事件 onmouseup 鼠标进…...
虚幻4学习笔记(12)操控导入的角色、动画蓝图、播放蒙太奇和打包、角色重定向
虚幻4学习笔记 操控导入的角色设置鼠标旋转关掉动态模糊 动画蓝图、播放蒙太奇和打包角色走路奔跑动画shift 奔跑F 跳舞移动打断 跳舞 打包角色重定向姿势调整解决跑步 腿分太开隐藏剑 B站UP谌嘉诚课程:https://www.bilibili.com/video/BV164411Y732 操控导入的角色…...
hive with tez:无法从链中的任何提供者加载aws凭据
环境信息 hadoop 3.1.0 hive-3.1.3 tez 0.9.1 问题描述 可以从hadoop命令行正确地访问s3a uri。我可以创建外部表和如下命令: create external table mytable(a string, b string) location s3a://mybucket/myfolder/; select * from mytable limit 20; 执行正…...
Ubuntu修改静态IP、网关和DNS的方法总结
Ubuntu修改静态IP、网关和DNS的方法总结 ubuntu系统(其他debian的衍生版本好像也可以)修改静态IP有以下几种方法。(搜索总结,可能也不太对) /etc/netplan (use) Ubuntu 18.04开始可以使用netplan配置网络࿰…...
Eureka服务器注册
一。Eureka服务器注册 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…...
Windows安装GPU版本的pytorch详细教程
文章目录 chatGLM2-6B安装教程正式安装 chatGLM2-6B ChatGLM2-6B版本要装pytorch2.0,而且要2.0.1 ,因此CUDA不能用12.0 ,也不能用10.0,只能用11.x 版本。 安装教程 pip install直接下载安装 官网: https://pytorch.…...
理解Kruskal算法的前提----深入理解并查集【超简单~】
并查集的实现思路 并查集主要分为两个部分:第一部分就是需要找到点对应的祖宗节点,第二部分,是要将属于同一个集合节点的祖宗节点进行统一,也就是结合操作。 Find函数实现 // parent数组用来存储下标值所对应的父节点值 // 比如…...
Jenkins+Gitee+Docker+Ruoyi项目前后端分离部署
前言 描述:本文主要是用来记录 如何用标题上的技术,部署到云服务器上通过ip正常访问。 一、总览 1.1、Docker做的事 拉取 mysql 镜像拉取 redis 镜像拉取 jdk 镜像拉取 nginx 镜像 解释说明:前端项目的打包文件放在 nginx容器运行。后端…...
笙默考试管理系统-MyExamTest----codemirror(23)
笙默考试管理系统-MyExamTest----codemirror(23) 目录 笙默考试管理系统-MyExamTest----codemirror(23) 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙…...
重学Java (一) 泛型
1. 前言 泛型编程自从 Java 5.0 中引入后已经超过15个年头了。对于现在的 Java 码农来说熟练使用泛型编程已经是家常便饭的事情了。所以本文就在不对泛型的基础使用在做说明了。 如果你还不会使用泛型的话,可以参考下面两个链接 Java 泛型详解The Java™ Tutorial…...
Docker 部署 Redis 服务
拉取最新版本的 Redis 镜像: $ sudo docker pull redis:latest在本地预先创建好 data 目录和 conf/redis.conf 文件。 使用以下命令来运行 Redis 容器: $ sudo docker run -itd --name redis --privilegedtrue -p 6379:6379 -v /home/ubuntu/docker/redis/data:/data -v /ho…...
阿里云产品试用系列-负载均衡 SLB
阿里云负载均衡(Server Load Balancer,简称SLB)是云原生时代应用高可用的基本要素。通过将流量分发到不同的后端服务来扩展应用系统的服务吞吐能力,消除单点故障并提升应用系统的可用性。阿里云SLB包含面向4层的网络型负载均衡NLB…...
drf 对象级权限
drf 对象级权限 Django REST Framework(DRF)提供了对象级别权限(Object-level permissions)来控制特定对象的访问权限。 简单来说:通过视图类中的self.get_object(pk)得到一个obj对象(视图对象),在与requ…...
八大排序(二)--------冒泡排序
本专栏内容为:八大排序汇总 通过本专栏的深入学习,你可以了解并掌握八大排序以及相关的排序算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:八大排序汇总 🚚代码仓库:小小unicorn的代码仓库…...
SmartSQL 一款开源的数据库文档管理工具
建议直接蓝奏云下载安装 蓝奏云下载:https://wwoc.lanzoum.com/b04dpvcxe 蓝奏云密码:123 项目介绍 SmartSQL 是一款方便、快捷的数据库文档查询、导出工具!从最初仅支持 数据库、CHM文档格式开始,通过不断地探索开发、集思广…...
代码随想录算法训练营第56天 | ● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 动态规划之编辑距离总结篇
文章目录 前言一、583. 两个字符串的删除操作二、72. 编辑距离三、动态规划之编辑距离总结篇总结 前言 一、583. 两个字符串的删除操作 两种思路:1.直接动态规划,求两个字符串需要删除的最小次数 2.采用子序列的和-最长公共子序列。思路一分析如下&#…...
矩阵 m * M = c
文章目录 题1题2 题1 (2023江苏领航杯-prng) 题目来源:https://dexterjie.github.io/2023/09/12/%E8%B5%9B%E9%A2%98%E5%A4%8D%E7%8E%B0/2023%E9%A2%86%E8%88%AA%E6%9D%AF/ 题目描述: (没有原数据,自己生成的数据) from Crypto.Util.number…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
