java并发机制锁的类型和实现
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并发机制锁的类型和实现的更多相关文章
- Java 并发机制底层实现 —— volatile 原理、synchronize 锁优化机制
本书部分摘自<Java 并发编程的艺术> 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JV ...
- Java 并发系列之二:java 并发机制的底层实现原理
1. 处理器实现原子操作 2. volatile /** 补充: 主要作用:内存可见性,是变量在多个线程中可见,修饰变量,解决一写多读的问题. 轻量级的synchronized,不会造成阻塞.性能比s ...
- Java并发机制的底层实现原理之volatile应用,初学者误看!
volatile的介绍: Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现 ...
- Java并发 - (无锁)篇6
, 摘录自葛一鸣与郭超的 [Java高并发程序设计]. 本文主要介绍了死锁的概念与一些相关的基础类, 摘录自葛一鸣与郭超的 [Java高并发程序设计]. 无锁是一种乐观的策略, 它假设对资源的访问是没 ...
- java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock
原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...
- 《Java并发编程的艺术》Java并发机制的底层实现原理(二)
Java并发机制的底层实现原理 1.volatile volatile相当于轻量级的synchronized,在并发编程中保证数据的可见性,使用 valotile 修饰的变量,其内存模型会增加一个 L ...
- 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile
章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...
- 从源码学习Java并发的锁是怎么维护内部线程队列的
从源码学习Java并发的锁是怎么维护内部线程队列的 在上一篇文章中,凯哥对同步组件基础框架- AbstractQueuedSynchronizer(AQS)做了大概的介绍.我们知道AQS能够通过内置的 ...
- Java并发编程锁系列之ReentrantLock对象总结
Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...
随机推荐
- dskinlite(uieasy mfc界面库)使用记录2:绘制动态元素(按钮控件绘制元素动态控制,改变图片和文字)
效果图:这4个分别是按钮按下后4种状态的效果 第88行是显示默认的按钮文字,没有id,SetWindowText改的就是它了 第87行是左边的图片,id是ico,可以通过程序控制 第89行是蓝色的文字 ...
- 解决ubuntu 图标消失问题(ubuntu 16)
如题,我的ubuntu 16 在安装了新内核并重启之后,所有的图标都消失了. (可能和新内核没有多大关系,我切回旧内核也那样) 是什么bug我不清楚,但是图标原有的位置还是可以点击的,仔细看图标还在, ...
- concurrent.futures性能阐述
python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算.这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型. IO密集型:读取文件,读取网络套接字频繁. 计算密集 ...
- Aspose.Words提示The document appears to be corrupted and cannot be loaded.
https://download.csdn.net/download/tomeatbj163/10428046
- appium java 滑动(js滑动和swipe滑动)
最近有一个页面的内容很多,有的元素需要滑动到底部才能看到,所以就研究一下滑动,下面是我学习到的两种滑动方式 一:用js滑动 用js滑动的思路是很简单,首先是先定位到这个元素,定位到之后不做任何操作,然 ...
- 受限filterbanks
2.Related works to filterbank learning 虽然DNN-HMM模型的性能比GMM-HMM模型相比,具有很大的优势,但是训练集和测试集之间的失配问题,也使得DNN-HM ...
- php-fpm 配置中pm的选择
另附豆瓣技术贴:https://www.douban.com/note/315222037/ 1.php-fpm优化参数介绍他们分别是:pm.pm.max_children.pm.start_serv ...
- spring深入学习(一)-----IOC容器
spring对于java程序员来说,重要性不可言喻,可以想象下如果没有他,我们要多做多少工作,下面一个系列来介绍下spring(5.x版本). spring模块 IOC概念 spring中最重要的两个 ...
- Unity加载外部图片
在这里记录一下在 Unity3D 中分别使用 WWW 和 IO 流加载外部图片 使用 WWW 加载 /// <summary> /// 使用 WWW 加载图片,并赋值给 _rawImage ...
- Automated generation of test oracles using a model-driven approach
一.基本信息 标题:Automated generation of test oracles using a model-driven approach 时间:2013 出版源:Information ...