Android---Synchronized 和 ReentrantLock
Synchronized 基本使用
1. 修饰实例方法
public class SynchronizedMethods{private int sum = 0;public synchronized void calculate(){sum = sum + 1;}
}
这种情况下的锁对象是当前实例对象,因此只有同一个实例对象调用此方法才会产生互斥效果;不同的实例对象之间不会有互斥效果。 比如如下代码:
上述代码是在不同线程中用不同的对象调用 printLog() 方法,彼此之间不会有排斥,运行结果如下:可以看出两个线程是交互执行的。
将上述代码做如下修改, 两个线程调用同一个对象的 printLog() 方法
执行效果如下, 只有某一个线程中的代码执行完后才会调用另外一个线程中的代码。此时两个线程之间是互斥的。
2. 修饰静态方法
如果 synchronized 修饰的是静态方法,则锁对象是当前类的 Class 对象。即使在不同线程中调用不同实例对象,也会有互斥效果。修改代码如下
执行结果如下,可以看出两个线程还是依次执行的。
3. 修饰代码块
如果 synchronized 修饰的是代码块,则锁对象是括号"()"里的对象。如下代码可以看出,任何 Object 对象都可以看着锁对象
执行结果如下,可以看出两个线程还是依次执行的。
实现细节
synchronized 既可以作用于方法也可以作用于代码块。但在实现上是有区别的,比如如下代码使用 synchronized 作用于代码块
使用 javap -c Foo 查看上述代码的字节码,如下
可以看出,编译成的字节码包含 monitorenter 和 monitorexit 俩个字节码指令。
注意:有两个 monitorexit。虚拟机需要保证当异常出现时也能释放锁,因此两个 monitorexit ,一个是代码正常执行结束后释放锁,一个是代码执行异常时释放锁。
synchronized 修饰方法,如下所示。被 synchronized 修饰方法被编译成字节码后,在方法的 flags 属性中会被标记为 ACC_SYNCHRONIZED。当虚拟机访问一个被标记为ACC_SYNCHRONIZED的方法时,会自动在方法开始和结束时添加 monitorenter 和 monitorexit 指令。
monitorenter 和 monitorexit 可以理解为一把具体的锁,这个锁中保存着两个比较重要的属性:计数器和指针。
计数器:代表当前线程一共访问了几次这把锁;
指针:指向持有这把锁的线程。
ReentrantLock 的基本使用
ReentrantLock 的使用同 Synchronized 优点不同,它的加锁和解锁需要手动完成。
如上代码所示,ReentrantLock.lock() 和 ReentrantLock.unlock() 都需要手动完成。运行效果如下。ReentrantLock 也能实现于 Synchronized 相同的效果。
注意:将 unlock() 操作放在 finally 代码块中,是因为 ReentrantLock 并不会自动释放锁,当异常发生时,确保释放锁操作一定会被执行(finally 里的代码在异常发生时,也能执行)。而 Synchronized 在异常发生时会自动释放锁。
公平锁实现
ReentrantLock 有一个带参数的构造器,如下。
默认情况下 Synchronized 和 ReentrantLock 都是非公平锁,但是 ReentrantLock 可以通过传入一个 true 来创建一个公平锁。
公平锁:通过同步队列来实现多个线程按照申请锁的先后顺序获取锁。
使用实例如下:
读写锁(ReentrantReadWriteLock)
在常见的开发中,经常会定义一个线程间共享的用作缓存的数据结构。比如一个较大的 Map,缓存中保存了全部的城市 Id 和 name 对应关系。这个大 Map 绝大部分时间提供读服务,而写操作占用的时间很少,通常是在服务器启动时初始化,然后可以每隔一段时间再刷新缓存的数据。但是写操作开始到结束之间,不能再有其它读操作进行,并且写操作完成之后的更新数据需要对后续的读操作可见。
使用 concurrent 包中的读写锁(ReentrantReadWriteLock)实现上述功能,只需要在读操作时获取读锁,写操作时获取写锁即可。当写锁被获取到时,后续的读写锁都会被阻塞,写锁缩释放后,所有操作继续执行。
读写锁的使用
1. 创建读写锁
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
2. 通过读写锁对象分别获取读锁(ReadLock)和写锁(Write Lock)
ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
ReentrantReadWriteLock.ReadLock writeLock = rwLock.writeLock();
3. 使用读锁同步缓存读操作,使用写锁同步缓存写操作
// 读操作
readLock.lock();
try{// 从缓存中读取数据
} finally{readLock.unlock();
}// 写操作
writeLock.lock();
try{// 想缓存中写入数据
} finally{writeLock.lock();
}
具体实现
如上代码,图中的 number 是线程中共享的数据,用来模拟缓存数据;图中1处,分别创建2个 Reader 线程并从缓存中读取数据,1个 Writer 将数据写入缓存中;图中2处,使用读锁(ReadLock)将读取数据的操作枷锁;图中3处,使用写锁(WriteLock)将写入数据到缓存中的操作加锁。
总结
● Java中两个实现同步的方式synchronized和ReentrantLock
● synchronized使用更简单,加锁和释放锁都是由虚拟机自动完成
● ReentrantLock需要开发者手动去完成,很Reentrantl ock的使用场景更多
公平锁和读写锁都可以在复杂场景中发挥重要作用。
相关文章:

Android---Synchronized 和 ReentrantLock
Synchronized 基本使用 1. 修饰实例方法 public class SynchronizedMethods{private int sum 0;public synchronized void calculate(){sum sum 1;} } 这种情况下的锁对象是当前实例对象,因此只有同一个实例对象调用此方法才会产生互斥效果;不同的…...
【解题报告】牛客挑战赛70 maimai
题目链接 这个挑战赛的 F F F是我出的,最后 zhoukangyang 爆标了。。。orzorz 记所有有颜色的边的属性集合 S S S 。 首先在外层容斥,枚举 S ∈ [ 0 , 2 w ) S\in [0,2^w) S∈[0,2w),计算被覆盖的的边中不包含 S S S 中属性,…...
算启新程 智享未来 | 紫光展锐携手中国移动共创数智未来
10月11日-13日,2023年中国移动全球合作伙伴大会在广州举行,此次大会以“算启新程 智享未来”为主题,与合作伙伴一起共商融合创新,共创数智未来。作为中国移动每年规模最大、最具影响力的盛会,吸引了数百家世界500强企业…...

thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢
thinkphp5.1 获取缓存cache(‘cache_name’)特别慢,php 7.0 unserialize 特别慢 场景: 项目中大量使用了缓存,本地运行非常快,二三百毫秒,部署到服务器后 一个表格请求就七八秒,最初猜想是数据库查询慢&am…...
【Linux】UNIX 术语中,换页与交换的区别和Linux 术语中,换页与交换的区别?
UNIX换页和交换的区别 在UNIX中,换页(Paging)是一种内存管理技术,用于在程序运行时动态地将其代码和数据从磁盘加载到内存中。当程序需要访问的页面不在内存中时,就会发生页错误(page error)&a…...
零基础学python之集合
文章目录 集合1、创建集合2、集合常见操作方法2、1 增加数据2、2 删除数据2、3 查找数据 3、总结 集合 目标 创建集合集合数据的特点集合的常见操作 1、创建集合 创建集合使用{}或set(), 但是如果要创建空集合只能使用set(),因为{}用来创建空字典。 …...

PromptScript:轻量级 DSL 脚本,加速多样化的 LLM 测试与验证
TL;DR 版本 PromptScript 是一个轻量级的 Prompt 调试用的 DSL (Yaml)脚本,以用于快速使用、构建 Prompt。 PromptScript 文档:https://framework.unitmesh.cc/prompt-script Why PromptScript ? 几个月前&…...

强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)
写在前面:本篇博文的内容来自李宏毅机器学习课程与自己的理解,同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…...
JUC之ForkJoin并行处理框架
ForkJoin并行处理框架 Fork/Join 它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。 类似于mapreduce 其实,在Java 8中引入的并行流计算,内部就是采用的ForkJoinPool来实现…...

【牛客面试必刷TOP101】Day8.BM33 二叉树的镜像和BM36 判断是不是平衡二叉树
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:牛客面试必刷TOP101 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&…...

CSS padding(填充)
CSS padding(填充)是一个简写属性,定义元素边框与元素内容之间的空间,即上下左右的内边距。 padding(填充) 当元素的 padding(填充)内边距被清除时,所释放的区域将会受到…...

C语言达到什么水平才能从事单片机工作
C语言达到什么水平才能从事单片机工作 从事单片机工作需要具备一定的C语言编程水平。以下是几个关键要点:基本C语言知识: 掌握C语言的基本语法、数据类型、运算符、流控制语句和函数等基本概念。最近很多小伙伴找我,说想要一些C语言学习资料&…...
Java架构师理解SAAS和多租户
目录 1 云服务的三种模式1.1 IaaS(基础设施即服务)1.2 PaaS(平台即服务)1.3 SaaS(软件即服务)1.4 区别与联系2 SaaS的概述2.1 Saas详解2.2 应用领域与行业前景2.3 Saas与传统软件对比3 多租户SaaS平台的数据库方案3.1 多租户是什么3.2 需求分析3.3 多租户的数据库方案分析…...

关于Java线程池相关面试题
【更多面试资料请加微信号:suns45】 https://flowus.cn/share/f6cd2cbe-627a-435f-a6e5-1395333f92e8 【FlowUs 息流】📣suns-Java资料 访问密码:【请加微信号:suns45】 ————线程相关的面试题———— 0:创建线…...

ExcelBDD Python指南
在Python里面支持BDD Excel BDD Tool Specification By ExcelBDD Method This tool is to get BDD test data from an excel file, its requirement specification is below The Essential of this approach is obtaining multiple sets of test data, so when combined with…...
基于深度学习的驾驶员疲劳监测系统的设计与实现
点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/88421622?spm1001.2014.3001.5503 基于深度学习的驾驶员疲劳监测系统的设计与实现 1 绪论 在21世纪,各国的经济飞速发展,人民越来越富裕,道路上的汽车也逐…...

B树、B+树详解
B树 前言 首先,为什么要总结B树、B树的知识呢?最近在学习数据库索引调优相关知识,数据库系统普遍采用B-/Tree作为索引结构(例如mysql的InnoDB引擎使用的B树),理解不透彻B树,则无法理解数据…...

使用hugging face开源库accelerate进行多GPU(单机多卡)训练卡死问题
目录 问题描述及配置网上资料查找1.tqdm问题2.dataloader问题3.model(input)写法问题4.环境变量问题 我的卡死问题解决方法 问题描述及配置 在使用hugging face开源库accelerate进行多GPU训练(单机多卡)的时候,经常出现如下报错 [E Process…...

IDEA 修改插件安装位置
不说假话,一定要看到最后,不然你以为我为什么要自己总结!!! IDEA 修改插件安装位置 前言步骤 前言 IDEA 默认的配置文件均安装在C盘,使用时间长会生成很多文件,这些文件会占用挤兑C盘空间&…...
牛客网SQL160
国庆期间每类视频点赞量和转发量_牛客题霸_牛客网 select * from ( select tag,dt, sum(单日点赞量)over(partition by tag order by dt rows between 6 preceding and 0 following), max(单日转发量)over(partition by tag order by dt rows between 6 preceding and 0 follo…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...