synchronized 和 volatile,是最基础的两个锁!

volatile是轻量级锁,它在多核处理器开发中保证了共享变量的可见性。即当一个线程修改一个共享变量时,其他线程能够读到这个修改的值。它比syncronized使用和成本更低。

要说volatile的实现原理,就要先看一下cpu基本概念。java语言规范第3版中对volatile的定义如下:

volatile会添加一条lock# 前缀的指令在汇编前,使数据立即从缓冲区刷到主内存,同时通过缓存一致性协议,将其他缓存了该内存地址的缓存失效。从而达到内存可见的目的。

synchronized是重量级锁,它是存放在java对象头里,如图:

在运行期间,mark word里的数据会随锁标志位变化而变化。

syncronized 实现锁方法实现为,在进入前加入monitorenter和在退出时monitorexit,每个对象都有一个monitor!

锁分偏向锁,轻量级锁和重量级锁,偏向锁的前提是线程切换的可能性比较少,在对象头中保存线程偏向标识,在释放锁只需判定该偏向锁是否为需要的即可,如果有竞争则进行锁升级,到轻量级锁,再到重量级锁。锁只能正向升级,不能反向降级;

cpu中实现原子操作原理为,首先处理器能自动保证基本的内存操作的原子性,从系统内存读取或写入一个字节是原子的,即当一个处理器在读取一个字节时,其他处理器是不能访问这个字节的内存地址的。另外比如某处理器能自动保证单处理器对同一个缓存行里进行16/32/64位的操作是原子的,另外的复杂操作如跨总线宽度跨多缓存行跨页表的访问则是不能保证原子的。但是,处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性,从而使锁一类的操作得到了保障。

其中,总线锁定开销比较大。实现为使用处理器提供的一个lock # 信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,从而使该处理器以独占方式使用内存。

缓存锁定机制则是为了减轻总线锁带来的巨大开销而出来的,即如果某个操作被处理器缓存在处理器的缓存行里,并且声明了lock #操作,就可以只修改内部的内存地址,并允许它的缓存一致性来保证原子性,缓存一致性会阻止同时修改两个以上处理器缓存的内存区域数据,当其他处理器回写锁定的缓存行时,会使缓存行失效,从而保证操作的原子性。但是两种情况不能用缓存锁定,一操作的数据不能被缓存在处理器内部时,或者操作数据跨多个缓存行时,使用总线锁定;二处理器不支持缓存锁定;

jmm内存模型为,主内存和工作存,每个线程直接与工作内存交互,在不确定的时间点将数据刷入主内存,只有刷入主内存的数据对其他线程才是可见的。

锁机制保证了只有获得锁的线程才能操作锁定的内存区域,有偏向锁,轻量级锁和互斥锁,但除了偏向锁外,其他两个都是用cas来实现,即获取锁时用cas保证获取,退出同步块时使用循环cas释放锁。由此可见,cas在java锁实现中的重要地位。

但是我们也要明白 cas 也有自己的弊端,如ABA问题,循环时间长时开销很大;

基于cas,java中实现多个常用的原子操作,一般以 AtomicXXX 命名,在需要强一致性多线程操作场景,可以派上用场。

java concurrent 锁_java并发机制锁的类型和实现相关推荐

  1. java lock 对象_Java并发编程锁系列之ReentrantLock对象总结

    Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...

  2. java投票锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  3. java 共享锁 独占锁_Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家取排队本着先来 ...

  4. java公平索非公平锁_Java 并发编程中使用 ReentrantLock 替代 synchronized

    Java 5 引入的 Concurrent 并发库软件包中,提供了 ReentrantLock 可重入同步锁,用来替代 synchronized 关键字原语,并可提供更好的性能,以及更强大的功能.使用 ...

  5. java 并发锁_Java并发教程–锁定:内在锁

    java 并发锁 在之前的文章中,我们回顾了在不同线程之间共享数据的一些主要风险(例如原子性和可见性 )以及如何设计类以安全地共享( 线程安全的设计 ). 但是,在许多情况下,我们将需要共享可变数据, ...

  6. java 并发锁_Java并发教程–重入锁

    java 并发锁 Java的synced关键字是一个很棒的工具–它使我们可以通过一种简单可靠的方式来同步对关键部分的访问,而且也不难理解. 但是有时我们需要对同步进行更多控制. 我们要么需要分别控制访 ...

  7. java重入锁_java并发编程:可重入锁是什么?

    释义 广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁.ReentrantLock和sync ...

  8. java公平锁和非公平锁_java并发编程学习之再谈公平锁和非公平锁

    在java并发编程学习之显示锁Lock里有提过公平锁和非公平锁,我们知道他的使用方式,以及非公平锁的性能较高,在AQS源码分析的基础上,我们看看NonfairSync和FairSync的区别在什么地方 ...

  9. java队列加锁_java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列...

    前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器.它是构建锁或者其他同步组件的基础框架(如ReentrantLock.ReentrantRead ...

最新文章

  1. AI+IOT战火升级:未来人工智能抢人大战
  2. applicationContext.xml 的位置问题
  3. canvas 添加 竖版文字_CSS题目系列(4) - 文字穿透遮罩层
  4. Mac 完全卸载 Java
  5. C语言 跨函数使用内存.
  6. php 命令行方式运行时 几种传入参数的方式
  7. 2019年5月 Teams Community Call (China)
  8. 数学有多震撼?!我真的没有在开车!
  9. 第13课 智商问题 《小学生C++趣味编程》
  10. loadrunner 脚本优化-事务时间简介
  11. 动态调整linux分区大小,GParted 动态调整Linux分区大小
  12. ES8新特性_ES8中对象方法的扩展---JavaScript_ECMAScript_ES6-ES11新特性工作笔记052
  13. 2007.05.07 不再如此堕落
  14. Spring源码解析目录
  15. 象棋在线对战网页源码源码安装
  16. 谈谈我对《ThoughtWorks文集》中多语言开发部分的看法
  17. stata陈强:计量经济学及stata应用_陈强 第四章 一元线性回归
  18. 企业微信登录报错:应用程序无法正常启动(0xc0000142);Win10应用程序无法正常启动0xc0000142错误的解决方法
  19. 鼠标移动效果html5,js实现鼠标左右移动,图片也跟着移动效果
  20. python画羊_python编程羊车门问题代码示例

热门文章

  1. 你真的了解.NET中的String吗?
  2. nodejs常用模块-url
  3. Linux 安装USB摄像头
  4. 二叉树特性及详细例子
  5. [转载]全面解读软件版本的标志
  6. es7 async 前置依赖
  7. javascript --- [虚拟DOM] 初始化 实现
  8. dart --- 简单的闭包
  9. vue --- v-text、v-show、v-if、v-else
  10. Linux网络/firewalld和netfilter/netfilter/iptables语法