前言

又过去了一个周末,最近陆陆续续的看了《并发编程的艺术》一书,对锁有不少感悟,这次就聊聊Java中的锁事。本文纯粹是漫谈,想到哪说到哪,但准确性肯定会保证,倘若有不正确之处,还请交流指正。

正文

作为Java开发, 说到锁第一时间想到的肯定是synchronized和juc包中的lock锁这俩兄弟,但如果眼光放开点,会发现还有很多其他的锁:集群/分布式环境下的分布式锁、mysql中的那一家子锁、操作系统中基于信号量/互斥量等构成的锁。。。上面说的是锁的应用场景,而说起锁本身,定义的类型也不少,什么悲观锁/乐观锁、独占锁/共享锁、读写锁、公平锁/非公平锁、重入锁、轻量级锁/重量级锁、自旋锁、偏向锁...

锁是干什么的?用个人的话来总结一下就是:用于控制不同访问来源对同一数据的访问顺序。也就是说锁的应用涉及到两个关键条件:不同访问来源(可以是不同线程、不同进程、不同APP)和操作同一数据(即共享的数据)。

下面对锁进行一下总结,首先按锁的实现思想分类:

    悲观锁和乐观锁属于锁的实现思想,synchronized是悲观锁,而基于乐观锁思想的实现是以CAS为基础构建的lock锁,同样mysql中的锁属于悲观锁,用redis或者zk构建的分布式锁也都是悲观锁,操作系统中基于信号量/互斥量等构建起来的锁也都属于悲观锁范畴。所以用悲观锁/乐观锁的思想标准来看锁,发现各种各样的锁定义其实都在这二者的思想范围内,没有能跑出该范围的。

独占锁/共享锁(读写锁)属于锁的占用类型,有这两种分类的原因就是为了提高系统的并发能力--读不影响读,这里可以再引申一步,mysql为了进一步提高并发能力通过数据多版本使得读跟写也不冲突。其实这里就是提高并发能力的一条线:先是不管读请求还是写请求统统排队进行,后来将读写分开提高读读的效率,再后来通过数据多版本使得读写可以同时进行,后面还能再提高吗?或许参考redis的单线程内存操作是一个方向,但对于复杂数据形式和大数据量却不适合。

公平锁和非公平锁主要针对的是获取锁的方式,公平就是一起排队先排队的先获取到锁,而非公平则表示一起竞争后来的也可能先获取到锁。公平锁的应用场景很少,而且主要是通过lock锁实现的,平时基本都是用非公平锁,无他,非公平锁并发量比公平的强了不止一点。但要额外说一下,lock锁中的非公平模式并不是完全的非公平,如果两次获取不到锁则进入阻塞队列,进入阻塞队列中后,它就只能按队列中的顺序挨个获取锁了,所以lock锁中的非公平模式并不是彻头彻尾的非公平,世间尚存一丝公道。。。

重入锁和非重入锁属于锁的性质,这个很好理解,可以同一获取锁的来源能重复获取的锁就是可重入的,非可重入的场景很少,我们平时接触的基本都是可重入。可重入的实现,基本原理都是在获取到锁之后,将对象记录下来,下次再触发获取锁的操作时先比对一下当前对象与已记录对象是否是同一个,是的话则能获取到锁,锁计数+1。详情可见ReentrantLock的加锁过程。

由于synchronized锁是JVM本身自带的关键字,所以针对synchronized锁做了很多优化,偏向锁/轻量级锁/自旋锁/重量级锁等概念都是来自于此(对synchronized锁等讲解可移步博主之前写过的一/二/三系列【https://i.cnblogs.com/posts?cateId=1466867&page=1】)。其实从原理上来说,自旋锁不是锁,只是在获取不到锁时先自循环一定次数继续尝试获取锁,如果仍然获取不到再阻塞,是针对很快能获取到锁的场景进行的优化处理。

下面再来几张图梳理下思绪:

扯扯Java中的锁的更多相关文章

  1. 深入介绍Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  2. 探究Java中的锁

    一.锁的作用和比较 1.Lock接口及其类图 Lock接口:是Java提供的用来控制多个线程访问共享资源的方式. ReentrantLock:Lock的实现类,提供了可重入的加锁语义 ReadWrit ...

  3. java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁(转载)

    之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...

  4. Java 中的锁

    Java中的锁分类 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分 ...

  5. Java中的锁(转)

    Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...

  6. java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

    之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...

  7. 深入理解Java中的锁

    转载:https://www.jianshu.com/p/2eb5ad8da4dc Java中的锁 常见的锁有synchronized.volatile.偏向锁.轻量级锁.重量级锁 1.synchro ...

  8. JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用

    Java 中无锁的线程安全整数 AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的,在使用的时候, 不可避免的会用到synchron ...

  9. Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

随机推荐

  1. css设置边框阴影;box-shadow的使用

    html代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  2. JavaScript基础函数的属性:记忆模式(019)

    函数在Javascript里是有属性的,因为它们是一种特殊对象.事实上,就算是没有明确声明,函数在最初就已经包含了一些固有的属性,比如所有函数都length这个属性,它可以指出函数声明了多少个参数: ...

  3. SpringBoot启动源码及自定义starter

    为什么springboot工程能够在mian方法中完成启动呢?需要大家掌握的有几个点:1.SPISPI在springboot中是去读取META-INF/spring.factories目录的配置文件内 ...

  4. Spring Cloud系列教程第九篇-Eureka自我保护机制

    Spring Cloud系列教程第九篇-Eureka自我保护机制 本文主要内容: 1:自我保护介绍 2:导致原因分析 3:怎么禁止自我保护 本文是由凯哥(凯哥Java:kagejava)发布的< ...

  5. windows php5.5安装redis扩展,并用redis存储session

    1.确定安装版本 先通过phpinfo()查看php的Compiler.Architecture.Thread Safety,其中Thread Safety如果是enabled,那么就是线程安全(ts ...

  6. 不懂SpringApplication生命周期事件?那就等于不会Spring Boot嘛

    学习方法之少废话:吹牛.装逼.叫大哥. 作者:A哥(YourBatman) 公众号:BAT的乌托邦(ID:BAT-utopia) 文末是否有彩蛋:有 目录 前言 正文 生命周期事件流程图 版本说明: ...

  7. 大话一个CPU(沙子是如何影响未来的)

    大话一个CPU(沙子是如何影响未来的) CPU是个啥? 先大体上了解一下 中央处理器 (英语:Central Processing Unit,缩写:CPU),是计算机的主要设备之一,功能主要是解释计算 ...

  8. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  9. 网页排名算法PagaRank

    网页排名算法PageRank PageRank,网页排名,又叫做网页级别.是一种利用网页之间的超链接数据进行计算的方法.它是由Google的两位创始人提出的. 对于用户而言,网页排名一般是比较主观的, ...

  10. git分支管理的策略和冲突问题

    目录 备注: 知识点 关于分支中的冲突 分支管理的策略 分支策略 备注: 本文参考于廖雪峰老师的博客Git教程.依照其博客进行学习和记录,感谢其无私分享,也欢迎各位查看原文. 知识点 git log ...