[转]JVM锁机制volatile/synchronized/lock

1.volatile实现原理

(1)聊聊并发(一)——深入分析Volatile的实现原理
--硬件级别锁实现,Lock前缀指令会引起处理器缓存(CPU高级缓存L1/L2/L3)回写到内存。一个处理器的缓存回写到内存会导致其他处理器的缓存无效。

2.JVM锁机制--synchronized

(1)深入JVM锁机制1-synchronized

--自旋锁、偏向锁

--synchronized的底层实现主要依靠Lock-Free的队列,基本思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。

(2)聊聊并发(二)——Java SE1.6中的Synchronized
--偏向锁—>轻量锁—>重量锁 比较

偏向锁

Hotspot的作者经过以往的研究发现大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要花费CAS操作来加锁和解锁,而只需简单的测试一下对象头的Mark
Word里是否存储着指向当前线程的偏向锁,如果测试成功,表示线程已经获得了锁,如果测试失败,则需要再测试下Mark
Word中偏向锁的标识是否设置成1(表示当前是偏向锁),如果没有设置,则使用CAS竞争锁,如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。

偏向锁的撤销:偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。偏向锁的撤销,需要等待全局安全点(在这个时间点上没有字节码正在执行),它会首先暂停拥有偏向锁的线程,然后检查持有偏向锁的线程是否活着,如果线程不处于活动状态,则将对象头设置成无锁状态,如果线程仍然活着,拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark

Word要么重新偏向于其他线程,要么恢复到无锁或者标记对象不适合作为偏向锁,最后唤醒暂停的线程。下图中的线程1演示了偏向锁初始化的流程,线程2演示了偏向锁撤销的流程。

轻量锁

即自旋锁

重量锁

即阻塞锁

锁的优缺点对比

偏向锁

加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。

如果线程间存在锁竞争,会带来额外的锁撤销的消耗。

适用于只有一个线程访问同步块场景。

轻量级锁

竞争的线程不会阻塞,提高了程序的响应速度。

如果始终得不到锁竞争的线程使用自旋会消耗CPU。

追求响应时间。

同步块执行速度非常快。

重量级锁

线程竞争不使用自旋,不会消耗CPU。

线程阻塞,响应时间缓慢。

追求吞吐量。

同步块执行速度较长。

(3)JVM锁实现探究1:synchronized初探

(4)JVM锁实现探究2:synchronized深探

锁升级机制:无锁—>偏向锁—>轻量锁—>重量锁

3.JVM锁机制AQS(AbstractQueuedSynchronizer)

(1)深入JVM锁机制2-Lock

--源码分析Java.util.concurrent.AbstractQueuedSynchronizer类

Lock VS Synchronized

AbstractQueuedSynchronizer通过构造一个基于阻塞的CLH队列容纳所有的阻塞线程,而对该队列的操作均通过Lock-Free(CAS)操作,但对已经获得锁的线程而言,ReentrantLock实现了偏向锁的功能。

synchronized的底层也是一个基于CAS操作的等待队列,但JVM实现的更精细,把等待队列分为ContentionList和EntryList,目的是为了降低线程的出列速度;当然也实现了偏向锁,从数据结构来说二者设计没有本质区别。但synchronized还实现了自旋锁,并针对不同的系统和硬件体系进行了优化,而Lock则完全依靠系统阻塞挂起等待线程。

当然Lock比synchronized更适合在应用层扩展,可以继承AbstractQueuedSynchronizer定义各种实现,比如实现读写锁(ReadWriteLock),公平或不公平锁;同时,Lock对应的Condition也比wait/notify要方便的多、灵活的多。

4.ReentrantLock

(1)JAVA并发编程学习笔记之ReentrantLock

--ReentrantLock是一个可重入的互斥锁,ReentrantLock由最近成功获取锁,还没有释放的线程所拥有

(2)ReentrantLock与synchronized的区别

--ReentrantLock的lock机制有2种,忽略中断锁和响应中断锁

--synchronized实现的锁机制是可重入的,主要区别是中断控制和竞争锁公平策略

原文地址:http://blog.csdn.net/asdf717/article/details/47252763

volatile、synchronized、lock有什么区别,以及在哪些场景下使用哪种方式?的更多相关文章

  1. JMM内存模型+volatile+synchronized+lock

    硬件内存模型: Java内存模型: 每个线程都有一个工作内存,线程只可以修改自己工作内存中的数据,然后再同步回主内存,主内存由多个内存共享. 下面 8 个操作都是原子的,不可再分的: 1)  lock ...

  2. 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?

    多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...

  3. Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)

    1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...

  4. java面试题之synchronized和lock有什么区别

    synchronized和lock的区别: 类别 synchronized lock 存在层次 java的关键字,在jvm层面上 是一个类 锁的释放 1.以获取锁的线程执行完同步代码,释放锁 2.线程 ...

  5. synchronized 和 Lock 有什么区别?(未完成)

    synchronized 和 Lock 有什么区别?(未完成)

  6. Synchronized和ReentTrantLock二者区别

    写在前面 Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock.这两种锁以及后面提到 ...

  7. C#多线程-volatile、lock关键字

    volatile是C#中最简单的一种同步关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,虽与java中的synchroni ...

  8. 三个线程,ABC 10次(volatile+synchronized)

    package ThreadABC; public class Share { private volatile int status; public int getStatus() { return ...

  9. java的两种同步方式, Synchronized与ReentrantLock的区别

    java在编写多线程程序时,为了保证线程安全,需要对数据同步,经常用到两种同步方式就是Synchronized和重入锁ReentrantLock. 相似点: 这两种同步方式有很多相似之处,它们都是加锁 ...

随机推荐

  1. 初始html(常用标签)

    今天我们来学习Web前端的一些知识,这一阶段需要记忆的东西相对来说比较多,需要花时间记忆以及做好练习. 一.HTML初识 1.web服务本质 import socket def main(): soc ...

  2. Node.js连接MongoDB

    使用monk访问mongodb mongodb.monk都安装了依赖的前提下: 首先启动MongoDB 服务:mongod: 进入了mongodb后台管理,再通过终端创建数据库:use monk-ap ...

  3. Android 超简单的拖动按钮 悬浮按钮 吸附按钮

    第一种    第二种    第一种实现方法 xml布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/re ...

  4. NIO(一)缓冲区

    I/O的基本概念 同步和异步的概念: 所谓的同步就是在发出一个请求的时候,如果没有得到结果,就不返回.即调用者主动等待返回结果. 所谓的异步:调用之后直接返回结果,一般通过回调函数来处理这个应用. 阻 ...

  5. 【ros】【bug】gtk2\3 冲突

    ORBSLAM2首次运行出现GTK冲突. Gtk-ERROR **: GTK+ 3 symbols detected. Using GTK+ 2.x and GTK+ 3 in the same pr ...

  6. Element-ui多选下拉实现全部与其他互斥

    1.以事件类型为例,给下拉绑定选项改变的change事件 2.当已选项个数大于1(即先选了其他,再选不限)且最后选的是不限时,取消其他选项选中状态: 当已选项个数等于2(即先选了不限,再选其他)且第一 ...

  7. Ruby 学习笔记(一)

    环境搭建 本文基于Mac OS,windowns坑较多,建议使用Mac. xcode-select -p 检查是否安装xcode-select, 如果没有,通过xcode-select --insta ...

  8. UVALive 4987 EvacuationPlan(dp,贪心)

    在所有避难所都有至少一只队伍的情况,总移动距离最小. 把队伍的位置和人都排序. 会发现,对于最后一个队伍i和最后一个避难所j, Case 1:pos[j]>=pos[i],那么i是距离j最近的一 ...

  9. 【CF799B】T-shirt buying(一道很水的小根堆)

    点此看题面 大致题意: 有\(n\)件T恤衫,告诉你每件T恤衫的价格以及它正面和反面的颜色(\(1≤\)颜色的编号\(≤3\)),现在有m个顾客,已知每个人想要的衣服的颜色(一件T恤衫只要有一面的颜色 ...

  10. 一键备份脚本 backup.sh

    做网站最重要的是什么?数据!数据,是网站之本,备份,是每一个站长都应该重视的事情.但同时,备份也是一件繁琐和重复的事情.所以,这些事情,肯定能做到自动化的.下面来介绍一下这个一键备份脚本 backup ...