当前位置: 首页 > news >正文

Java 中所有的锁

Java 中所有的锁

  • 1 乐观锁 VS 悲观锁
    • 悲观锁
    • 乐观锁
  • 2 自旋锁 VS 适应性自旋锁
    • 自旋锁
      • 优点
      • 缺点
  • 3 无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁
  • 4 公平锁 VS 非公平锁
  • 5 可重入锁 VS 非可重入锁
  • 6 独享锁(排他锁) VS 共享锁

Java 全栈知识体系

1 乐观锁 VS 悲观锁

适用场景解释
乐观锁适合写操作多的场景乐观锁在 Java 中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。
悲观锁适合读操作多的场景悲观锁在 Java 中使用 synchronized 关键字和 Lock 来实现。

悲观锁

悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。在 Java 中使用 synchronized 关键字和 Lock 来实现。

乐观锁

乐观锁认为自己在使用数据时不会有别的线程修改数据,因此在获取数据的时候不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试)。在 Java 中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。

2 自旋锁 VS 适应性自旋锁

自旋锁

阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长。

在许多场景中,同步资源的锁定时间很短,为了这一小段时间去切换线程,线程挂起和恢复现场的花费可能会让系统得不偿失。如果物理机器有多个处理器,能够让两个或以上的线程同时并行执行,我们就可以让后面那个请求锁的线程不放弃CPU的执行时间,看看持有锁的线程是否很快就会释放锁。

相同不同
自旋锁任何时候只能有一个获得锁如果资源已经被占用,资源申请者只能进入睡眠状态。等到锁被释放否再唤醒资源申请者,CPU再切换到新的资源申请者。
互斥锁任何时候只能有一个获得锁如果资源已经被占用,资源申请者不会进入睡眠状态,而是循环等待看锁是否被释放。如果锁被释放就会立即获得锁,而不需要经过唤醒和CPU上下文切换。

优点

在一些同步资源的锁定时间很短的业务中,线程挂起和恢复现的时间会比自旋的时间要长的适合使用自旋锁。

缺点

自旋锁本身是有缺点的,它不能代替阻塞。自旋等待虽然避免了线程切换的开销,但它要占用处理器时间。如果锁被占用的时间很短,自旋等待的效果就会非常好。反之,如果锁被占用的时间很长,那么自旋的线程只会白浪费处理器资源。所以,自旋等待的时间必须要有一定的限度,如果自旋超过了限定次数(默认是10次,可以使用-XX:PreBlockSpin来更改)没有成功获得锁,就应当挂起线程。

自旋锁的实现原理同样也是CAS,AtomicInteger中调用unsafe进行自增操作的源码中的do-while循环就是一个自旋操作,如果修改数值失败则通过循环来执行自旋,直至修改成功。

3 无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁

升级
升级
升级
无锁
偏向锁
轻量级锁
重量级锁
解释
无锁-
偏向锁通过对比Mark Word解决加锁问题,避免执行CAS操作。
轻量级锁轻量级锁是通过用CAS操作和自旋来解决加锁问题,避免线程阻塞和唤醒而影响性能。
重量级锁重量级锁是将除了拥有锁的线程以外的线程都阻塞。

4 公平锁 VS 非公平锁

5 可重入锁 VS 非可重入锁

6 独享锁(排他锁) VS 共享锁

相关文章:

  • 【基于Arduino的垃圾分类装置开发教程二传感器执行器操作】
  • java中static关键字具有什么功能呢?
  • springcloud 之gateway配置注意事项
  • JS BOM
  • 领英工具-领英精灵群发消息功能解析
  • [答疑]微信餐馆案例中,“启动二维码对应的程序”这个用例合理吗
  • Defocus(散焦)
  • jvm中对象内存空间的分配与回收
  • Shiro 550、721
  • Mybatis开启日志
  • linux中查看MySQL数据库表数据及结构并导入sql脚本
  • Maven dependency 详解
  • Hadoop搭建HA遇到的坑
  • Docker目录映射
  • INnoDB(索引与算法)
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • CAP 一致性协议及应用解析
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • java 多线程基础, 我觉得还是有必要看看的
  • JS变量作用域
  • js操作时间(持续更新)
  • Js基础——数据类型之Null和Undefined
  • Laravel Telescope:优雅的应用调试工具
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • python docx文档转html页面
  • SQLServer插入数据
  • ubuntu 下nginx安装 并支持https协议
  • 初识 beanstalkd
  • 诡异!React stopPropagation失灵
  • 回顾 Swift 多平台移植进度 #2
  • 码农张的Bug人生 - 初来乍到
  • 前端之React实战:创建跨平台的项目架构
  • 数组大概知多少
  • 追踪解析 FutureTask 源码
  • 阿里云移动端播放器高级功能介绍
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # include “ “ 和 # include < >两者的区别
  • $NOIp2018$劝退记
  • (1)(1.13) SiK无线电高级配置(五)
  • (2015)JS ES6 必知的十个 特性
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (c语言)strcpy函数用法
  • (C语言)逆序输出字符串
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (六)软件测试分工
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (转)visual stdio 书签功能介绍
  • (转载)从 Java 代码到 Java 堆
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET Project Open Day(2011.11.13)